Am actualizat sistemul meu si am instalat MySql 5.7.9 cu php pentru o aplicație web am de lucru pe. Am o interogare care este creat dinamic, și atunci când a alerga în versiunile mai vechi de MySql funcționează bine. Deoarece upgrade la 5.7 primesc aceasta eroare:
Expresie #1 SELECTAȚI listă nu este în clauza GROUP BY și conține neagregate coloana 'support_desk.mod_users_groups.group_id' care este nu este dependent funcțional de coloane în clauza GROUP BY; acest lucru este incompatibil cu sql_mode=only_full_group_by
Notă pagina de Manual pentru Mysql 5.7 pe tema Server SQL Moduri.
Aceasta este o interogare care mi-a dat probleme:
SELECT mod_users_groups.group_id AS 'value',
group_name AS 'text'
FROM mod_users_groups
LEFT JOIN mod_users_data ON mod_users_groups.group_id = mod_users_data.group_id
WHERE mod_users_groups.active = 1
AND mod_users_groups.department_id = 1
AND mod_users_groups.manage_work_orders = 1
AND group_name != 'root'
AND group_name != 'superuser'
GROUP BY group_name
HAVING COUNT(`user_id`) > 0
ORDER BY group_name
Am facut un google cu privire la problema, dar eu nu't înțelege only_full_group_by de ajuns să-mi dau seama ce trebuie să fac pentru a repara erorile de interogare. Pot transforma doar de pe only_full_group_by
opțiune, sau este ceva ce trebuie să fac?
Lasă-mă să știu dacă aveți nevoie de mai multe informații.
Puteți încerca să dezactivați only_full_group_by
setarea de executare următoarele:
mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
mysql> set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
MySQL 8 nu accept `NO_AUTO_CREATE_USER așa că trebuie să fie eliminate.
Aș adăuga doar group_id " la " GROUP BY
.
Când SELECTAȚI ' ing-o coloană care nu este parte a GRUPULUI DE acolo ar putea fi mai multe valori pentru care coloana în grupuri, dar nu va fi doar un spațiu pentru o singură valoare în rezultate. Astfel, baza de date de obicei trebuie să se spună exact cum să facă cele mai multe valori într-o valoare. De obicei, acest lucru se face cu o funcție agregată ca COUNT()
, SUM()
, MAX()
etc... eu spun de obicei pentru cele mai populare sisteme de baze de date insista pe acest lucru. Cu toate acestea, în MySQL înainte de versiunea 5.7 comportamentul implicit a fost mai iertator pentru că nu se va plânge și apoi alege în mod arbitrar orice valoare! Ea are, de asemenea, o ANY_VALUE () funcția, care ar putea fi folosit ca o soluție la această întrebare dacă într-adevăr nevoie de același comportament ca și mai înainte. Această flexibilitate vine la un cost, deoarece este non-deterministe, deci nu as recomanda-o daca nu ai un motiv foarte bun pentru a avea nevoie de ea. MySQL sunt acum de cotitură pe only_full_group_by
setarea implicit pentru motive întemeiate, astfel încât acesta's cel mai bun pentru a te obișnuiești cu el și face interogări respecte.
Deci, de ce răspunsul meu simplu de mai sus? Am'am făcut o serie de ipoteze:
group_id
este unic. Pare rezonabil, aceasta este o 'ID' la urma urmei.
group_name
este, de asemenea, unic. Acest lucru nu poate fi astfel o presupunere rezonabilă. Dacă acest lucru nu este cazul și ai un duplicat group_names
și apoi urmați sfatul meu pentru a adăuga group_id " la " GROUP BY
, s-ar putea găsi că aveți acum obține mai multe rezultate decât înainte, deoarece grupuri cu același nume, de acum va trebui rânduri separate în rezultate. Pentru mine, acest lucru ar fi mai bine decât cu aceste grupuri duplicat ascunse pentru că baza de date are liniște selectată o valoare arbitrar!
L's, de asemenea, o bună practică pentru a se califica toate coloanele cu masa lor numele sau alias când nu's mai mult de un tabel implicat...
SELECT
g.group_id AS 'value',
g.group_name AS 'text'
FROM mod_users_groups g
LEFT JOIN mod_users_data d ON g.group_id = d.group_id
WHERE g.active = 1
AND g.department_id = 1
AND g.manage_work_orders = 1
AND g.group_name != 'root'
AND g.group_name != 'superuser'
GROUP BY
g.group_name,
g.group_id
HAVING COUNT(d.user_id) > 0
ORDER BY g.group_name
puteți dezactiva mesajul de avertizare așa cum sa explicat în alte răspunsuri sau puteți înțelege ce's-a întâmplat și repara.
Ca de MySQL 5.7.5, implicit SQL modul include ONLY_FULL_GROUP_BY, care înseamnă că atunci când ești gruparea rânduri și apoi selectând ceva din grupuri, aveți nevoie pentru a a spune în mod explicit care rând în cazul în care selecția se face din.
Mysql are nevoie să știe care rând din grupul're în căutarea pentru, ceea ce vă oferă două opțiuni
`MIN()
MAX()
lista completă ANY_VALUE()
dacă sunteți sigur că toate rezultatele din interiorul grupului sunt la fel. docDacă tu nu't vreau pentru a face orice modificări în curent de interogare, apoi urmați pașii de mai jos -
sudo vim /etc/mysql/my.cnf
[mysqld] sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Utilizarea ANY_VALUE()
pentru a se referi la neagregate coloană.
SELECT name, address , MAX(age) FROM t GROUP BY name; -- fails
SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name; -- works
De MySQL 5.7 docs:
puteți obține același efect, fără dezactivarea
ONLY_FULL_GROUP_BY
prin utilizareaANY_VALUE()
pentru a se referi la neagregate coloana....
Această interogare ar putea fi invalid cu ONLY_FULL_GROUP_BY` activat, deoarece neagregate adresa de coloană din lista select nu este numit în GRUPUL DE clauze:
SELECTAȚI numele, adresa, MAX(vârsta) LA t GROUP BY nume; ...
Dacă știți că, pentru un anumit set de date, fiecare nume de valoare în fapt unic determină valoarea adresa, adresa este eficient din punct de vedere funcțional dependente pe nume. Spune MySQL pentru a accepta interogare, puteți utiliza
ANY_VALUE()
funcția:SELECTAȚI nume, ANY_VALUE(adresa), MAX(vârsta) LA t GROUP BY nume;
Voi încerca să explic de ce această eroare este vorba.
Pornind de la MySQL 5.7.5, opțiunea ONLY_FULL_GROUP_BY
este activată în mod implicit.
Astfel, potrivit standart SQL92 și mai devreme:
nu permite interogări pentru care selectați listă, AVÂND condiție, sau ORDIN DE listă se referă la neagregate coloane care nu sunt nici nume în clauza GROUP BY și nici nu sunt funcțional dependente (unic determinată de) GRUP DE coloane
Astfel, de exemplu:
SELECT * FROM `users` GROUP BY `name`;
Veți primi un mesaj de eroare după executarea interogării de mai sus.
#1055 - Expresie #1 SELECTAȚI listă nu este în clauza GROUP BY și conține neagregate coloana 'testsite.utilizator.id' care nu este dependent funcțional de coloane în clauza GROUP BY; acest lucru este incompatibil cu sql_mode=only_full_group_by
De ce?
Pentru că MySQL nu înțeleg exact de ce anumite valori din grupate înregistrări pentru a prelua, și acesta este punctul.
I. E. să presupunem că aveți acest înregistrările în "utilizatori" de masă:
Și va executa invalid query arăta de maniera de mai sus.
Și vei primi eroare arătat mai sus, pentru că, există 3 înregistrări cu numele "John", și este frumos, dar, toate acestea au diferite "e-mail" valori de câmp.
Deci, MySQL, pur și simplu, nu't a înțelege care dintre ele să se întoarcă în care rezultă grupate record.
Puteți rezolva această problemă, pur și simplu prin schimbarea interogare astfel:
SELECT `name` FROM `users` GROUP BY `name`
De asemenea, poate doriți să adăugați mai multe câmpuri pentru a SELECTA secțiunea, dar nu poți face asta, dacă acestea nu sunt agregate, dar nu este carja ai putea folosi (dar foarte recomandat):
SELECT ANY_VALUE(`id`), ANY_VALUE(`email`), `name` FROM `users` GROUP BY `name`
Acum, ați putea întreba, de ce folosind ANY_VALUE
este extrem de recomandat?
Pentru că MySQL nu't știu exact ce valoarea grupate înregistrări pentru a prelua și de a utiliza această funcție, vă cere să-i aducă oricare dintre ele (în acest caz, e-mail de prima înregistrare cu numele = John a fost preluat).
Exact nu pot veni cu orice idei cu privire la ce v-ar dori ca acest comportament să existe.
Vă rog, dacă nu mă înțelegi, citește mai multe despre modul de grupare în MySQL funcționează, este foarte simplu.
Și până la sfârșitul anului, aici este unul mai simplu, dar valabil interogare.
Dacă doriți să interogare total de utilizatori conta potrivit disponibile vârstele, poate doriți să scrie în jos această interogare
SELECT `age`, COUNT(`age`) FROM `users` GROUP BY `age`;
Care este pe deplin valabilă, în conformitate cu MySQL reguli.
Și așa mai departe.
Este important să se înțeleagă exact ceea ce este problema și numai atunci scrie soluția.
Eu sunt, folosind Laravel 5.3, mysql 5.7.12, pe laravel homestead (0.5.0, cred)
Chiar și după ce în mod explicit stabilirea de editare /etc/mysql/my.cnf
pentru a reflecta:
[mysqld]
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Am fost primiți în continuare eroarea.
Am avut de a schimba `config/database.php de "adevărat" la "false":
'mysql' => [
'strict' => false, //behave like 5.6
//'strict' => true //behave like 5.7
],
Lecturi suplimentare:
https://laracasts.com/discuss/channels/servers/set-set-sql-mode-on-homestead https://mattstauffer.co/blog/strict-mode-and-other-mysql-customizations-in-laravel-5-2
Dacă sunteți folosind wamp 3.0.6 sau orice versiune superioară, altele decât cele stabil 2.5 tu ar putea confrunta cu această problemă, în primul rând, problema este cu sql . trebuie să-numele câmpurilor în mod corespunzător. dar există o altă cale prin care poți să-l rezolve. faceți clic pe pictograma verde de wamp. mysql>mysql setări-> sql_mode->nici unul. sau de la consola puteți modifica valorile implicite.
mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
mysql> set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Plus de linii (mentionez mai jos) in fisierul : /etc/mysql/my.cnf
[mysqld]
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Funcționează bine pentru mine. Versiune Server: 5.7.18-0ubuntu0.16.04.1 - (Ubuntu)
Pentru mac:
1.Copia implicit mi-default.cnf /etc/my.cnf
sudo cp $(brew --prefix mysql)/support-files/my-default.cnf /etc/my.cnf
2.Schimba sql_mode mea.cnf folosind editorul preferat și setați-o la acest
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
3.Reporniți serverul MySQL.
mysql.server restart
Aceasta este ceea ce m-a ajutat să înțeleagă întreaga problemă:
Și în următoarele alt exemplu de o problematică de interogare.
Problematic:
SELECT COUNT(*) as attempts, SUM(elapsed) as elapsedtotal, userid, timestamp, questionid, answerid, SUM(correct) as correct, elapsed, ipaddress FROM `gameplay`
WHERE timestamp >= DATE_SUB(NOW(), INTERVAL 1 DAY)
AND cookieid = #
Rezolvată prin adăugarea acest scop:
GROUP BY timestamp, userid, cookieid, questionid, answerid, elapsed, ipaddress
Notă: a se Vedea mesajul de eroare in PHP, vă spune în cazul în care problema se află.
Exemplu:
MySQL query eroare 1140: În agregate de interogare fără GRUP DE, expresie #4 SELECTAȚI listă conține neagregate coloana 'db.gameplay-ul.timestamp'; acest lucru este incompatibil cu sql_mode=only_full_group_by - Interogarea: SELECT COUNT (*), ca încercări, SUM(scurs), ca elapsedtotal, userid, timestamp, questionid, answerid, SUMA(corect) ca fiind corecte, scurs, adresa ip DE la gameplay-ul În cazul în CARE timestamp >= DATE_SUB(NOW(), INTERVAL de 1 ZI) ȘI userid = 1
În acest caz, expresia #4 a fost lipsă în GRUPUL DE.
Puteți adăuga un index unic " la " group_id; dacă sunteți sigur că
group_id` este unic.
Se poate rezolva cazul dumneavoastră, fără a modifica interogarea.
Un răspuns cu întârziere, dar nu a fost menționat încă în răspunsuri. Poate că ar trebui să finalizeze deja răspunsuri complete disponibile. Cel puțin asta a făcut rezolva cazul meu atunci când am avut de a împărți o masă cu prea multe domenii.
Dacă aveți această eroare cu Symfony folosind doctrina query builder, și dacă această eroare este cauzată de o orderBy :
Să acorde o atenție pentru a "alege" pe coloana pe care doriți să groupBy, și de a folosi
addGroupBy "în loc de" groupBy` :
$query = $this->createQueryBuilder('smth')->addGroupBy('smth.mycolumn');
Funcționează pe Symfony3 -
Du-te la mysql sau phpmyadmin și selectați baza de date apoi, pur și simplu executa această interogare și va funcționa. Sale de lucru bine pentru mine.
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
Îmi cer scuze pentru că nu-ți folosești exact SQL
Am folosit această interogare pentru a depăși Mysql avertizare.
SELECT count(*) AS cnt, `regions_id`
FROM regionables
WHERE `regionable_id` = '115' OR `regionable_id` = '714'
GROUP BY `regions_id`
HAVING cnt > 1
notă cheia pentru mine fiind
count(*) AS cnt