Zaktualizowałem system i zainstalowałem MySql 5.7.9 z php dla aplikacji internetowej, nad którą pracuję. Mam zapytanie, które jest tworzone dynamicznie, a kiedy działa w starszych wersjach MySql, działa dobrze. Od aktualizacji do 5.7 pojawia się ten błąd:
Wyrażenie nr 1 listy SELECT nie znajduje się w klauzuli GROUP BY i zawiera niezagregowaną kolumnę „support_desk.mod_users_groups.group_id”, która nie jest funkcjonalnie zależna od kolumn w klauzuli GROUP BY; jest to niezgodne z trybem_sql = only_full_group_by
Zwróć uwagę na stronę Podręcznik dla MySQL 5.7 na temat trybów SQL serwera .
Oto pytanie, które sprawia mi problemy:
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
Zrobiłem trochę googling na ten temat, ale nie rozumiem only_full_group_by
wystarczająco dużo, aby dowiedzieć się, co muszę zrobić, aby naprawić zapytanie. Czy mogę po prostu wyłączyć tę only_full_group_by
opcję, czy jest coś jeszcze, co muszę zrobić?
Daj mi znać, jeśli potrzebujesz więcej informacji.
źródło
not a GROUP BY expression
” To jest to. Równie dobrze mogą mieć numeryczny kod błędu i w ogóle nie mieć wiadomości.Odpowiedzi:
Chciałbym tylko dodać
group_id
doGROUP BY
.Kiedy
SELECT
ing kolumnę, która nie jest częściąGROUP BY
może istnieć wiele wartości dla tej kolumny w obrębie grupy, ale nie będzie tylko przestrzeń dla pojedynczej wartości w wynikach. Tak więc baza danych zwykle wymaga dokładnego powiedzenia, jak przekształcić te wielokrotne wartości w jedną wartość. Zwykle odbywa się to z zagregowanej funkcji takich jakCOUNT()
,SUM()
,MAX()
itp ... mówię zwykle , ponieważ większość innych popularnych systemów baz danych nalegać na to. Jednak w MySQL przed wersją 5.7 zachowanie domyślne było bardziej wybaczające, ponieważ nie narzeka, a następnie arbitralnie wybiera dowolną wartość ! Ma równieżANY_VALUE()
funkcja, która może być wykorzystana jako inne rozwiązanie tego pytania, jeśli naprawdę potrzebujesz takiego samego zachowania jak wcześniej. Ta elastyczność wiąże się z pewnym kosztem, ponieważ jest niedeterministyczna, więc nie poleciłbym jej, chyba że masz bardzo dobry powód, aby jej potrzebować. MySQL terazonly_full_group_by
domyślnie włącza to ustawienie z dobrych powodów, więc najlepiej jest się do tego przyzwyczaić i dostosować zapytania.Więc dlaczego moja prosta odpowiedź powyżej? Podjąłem kilka założeń:
1)
group_id
jest wyjątkowy. Wydaje się rozsądne, w końcu jest to „dowód osobisty”.2)
group_name
jest również wyjątkowy. To może nie być tak rozsądne założenie. Jeśli tak nie jest i masz trochę duplikatów,group_names
a następnie postępujesz zgodnie z moją radą, aby dodaćgroup_id
doGROUP BY
, może się okazać, że teraz otrzymujesz więcej wyników niż wcześniej, ponieważ grupy o tej samej nazwie będą teraz miały osobne wiersze w wynikach. Dla mnie byłoby to lepsze niż ukrycie tych zduplikowanych grup, ponieważ baza danych po cichu wybrała dowolną wartość!Dobrą praktyką jest również kwalifikowanie wszystkich kolumn za pomocą nazwy tabeli lub aliasu, gdy w grę wchodzi więcej niż jedna tabela ...
źródło
GROUP BY
W swoim zapytaniu nie ma nawet klauzuli, ale pojawia się ten błąd.Możesz spróbować wyłączyć to
only_full_group_by
ustawienie, wykonując następujące czynności:MySQL 8 nie akceptuje,
NO_AUTO_CREATE_USER
więc należy go usunąć.źródło
SELECT COUNT(*), t.* FROM my_table t GROUP BY col
a masz 20-50 kolumn, czy chcesz poświęcić tyle czasu, dodając każdą kolumnę do Grupuj według?SELECT @@sql_mode;
a następnie dodając wynik stamtąd do my.cnf:sql_mode=[list of modes from query, minus ONLY_FULL_GROUP_BY]
możesz wyłączyć komunikat ostrzegawczy, jak wyjaśniono w innych odpowiedziach, lub zrozumieć, co się dzieje, i naprawić.
Począwszy od MySQL 5.7.5, domyślny tryb SQL zawiera ONLY_FULL_GROUP_BY, co oznacza, że kiedy grupujesz wiersze, a następnie wybierasz coś z tych grup, musisz wyraźnie powiedzieć, z którego wiersza należy dokonać tego wyboru.
Mysql musi wiedzieć, którego wiersza w grupie szukasz, co daje dwie opcje
group by rect.color, rect.value
która może być tym, czego chcesz w niektórych przypadkach, w przeciwnym razie zwrócą duplikaty wyników w tym samym kolorze, którego możesz nie chciećAVG()
MIN()
MAX()
pełna listaANY_VALUE()
jeśli masz pewność, że wszystkie wyniki w grupie są takie same. dokźródło
FIRST()
metodę / funkcję?ONLY_FULL_GROUP_BY
domyślnieJeśli nie chcesz wprowadzać żadnych zmian w bieżącym zapytaniu, wykonaj następujące czynności -
sudo vim /etc/mysql/my.cnf
A
aby przejść do trybu wstawianiaKopiuj i wklej
Wpisz,
esc
aby wyjść z trybu wprowadzania:wq
aby zapisać i zamknąć vim.sudo service mysql restart
aby zrestartować MySQL.źródło
paginate
funkcję.my.cnf
pliku to/etc
. Als zauważa nową składnię odMySQL 5.7.8:
sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Użyj,
ANY_VALUE()
aby odnieść się do niezagregowanej kolumny.Z dokumentów MySQL 5.7 :
źródło
ANY_VALUE
w podobnych dyskusjach nigdzie indziej nie wspomniano - działa idealnie dla mnie z moimGROUP_BY
contains nonaggregated column
błędem.Spróbuję wyjaśnić ci, na czym polega ten błąd.
Począwszy od MySQL 5.7.5, opcja
ONLY_FULL_GROUP_BY
jest domyślnie włączona.Zatem zgodnie ze standardowym SQL92 i wcześniejszymi wersjami:
( czytaj więcej w dokumentach )
Na przykład:
Po wykonaniu zapytania powyżej pojawi się komunikat o błędzie.
Dlaczego?
Ponieważ MySQL nie rozumie dokładnie, jakie pewne wartości z zgrupowanych rekordów pobrać, i o to właśnie chodzi.
IE pozwala powiedzieć, że masz te rekordy w swojej
users
tabeli:I wykonasz nieprawidłowe zapytanie pokazane powyżej.
Pojawi się błąd pokazany powyżej, ponieważ istnieją 3 rekordy z nazwą
John
i jest to miłe, ale wszystkie mają różneemail
wartości pól.Tak więc MySQL po prostu nie rozumie, który z nich zwrócić w wynikowym zgrupowanym rekordzie.
Możesz rozwiązać ten problem, po prostu zmieniając zapytanie w następujący sposób:
Możesz także chcieć dodać więcej pól do sekcji SELECT, ale nie możesz tego zrobić, jeśli nie są agregowane, ale istnieje kula, której możesz użyć (ale zdecydowanie nie jest to zalecane):
Teraz możesz zapytać, dlaczego używanie nie
ANY_VALUE
jest wysoce zalecane?Ponieważ MySQL nie do końca wie, jaką wartość zgrupowanych rekordów pobrać, a korzystając z tej funkcji poprosisz ją o pobranie dowolnego z nich (w tym przypadku pobrano e-maila z pierwszym rekordem o nazwie = John).
Dokładnie nie mogę wymyślić żadnych pomysłów, dlaczego chcesz, aby takie zachowanie istniało.
Jeśli mnie nie rozumiesz, przeczytaj więcej o tym, jak działa grupowanie w MySQL, jest to bardzo proste.
I na koniec, oto jeszcze jedno proste, ale prawidłowe zapytanie.
Jeśli chcesz sprawdzić całkowitą liczbę użytkowników według dostępnych grup wiekowych, możesz zapisać to zapytanie
Co jest w pełni poprawne, zgodnie z zasadami MySQL.
I tak dalej.
Ważne jest, aby zrozumieć, na czym dokładnie polega problem, i dopiero wtedy zanotuj rozwiązanie.
źródło
GROUP BY DAY(created_date)
? Wygląda na to, że nie działa, jeśliDAY()
zostanie dodany.Korzystam z Laravel 5.3, mysql 5.7.12, na laravel homestead (0,5.0, jak sądzę)
Nawet po jawnym ustawieniu edycji w
/etc/mysql/my.cnf
celu odzwierciedlenia:Nadal otrzymywałem błąd.
Musiałem zmienić
config/database.php
ztrue
nafalse
:Dalsza lektura:
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
źródło
Jeśli używasz wamp 3.0.6 lub dowolnej wyższej wersji innej niż stabilna 2.5, możesz napotkać ten problem, po pierwsze, problem dotyczy sql. musisz odpowiednio nazwać pola. ale jest inny sposób na rozwiązanie tego problemu. kliknij zieloną ikonę wampa. mysql-> ustawienia mysql-> tryb_sql-> brak. lub z konsoli możesz zmienić wartości domyślne.
źródło
show variables like '%sql_mode%';
bazując na tym, co powiedział, wstaw polecenie w wierszu polecenia mysql, ustawienie trybu_sql ujawni sięDodanie linii (wymienionych poniżej) w pliku: /etc/mysql/my.cnf
Pracuj dobrze dla mnie. Wersja serwera: 5.7.18-0ubuntu0.16.04.1 - (Ubuntu)
źródło
Przejdź do mysql lub phpmyadmin i wybierz bazę danych, a następnie po prostu uruchom to zapytanie i będzie działać. Dla mnie działa dobrze.
źródło
Dla Maca:
1. Skopiuj domyślny plik my-default.cnf do /etc/my.cnf
2.Zmień tryb sql_mode w pliku my.cnf za pomocą swojego ulubionego edytora i ustaw go w ten sposób
3. Uruchom ponownie serwer MySQL.
źródło
To pomogło mi zrozumieć cały problem:
A w kolejnym przykładzie problematycznego zapytania.
Problematyczny:
Rozwiązany przez dodanie tego na końcu:
Uwaga: Zobacz komunikat o błędzie w PHP, który informuje, gdzie leży problem.
Przykład:
W tym przypadku brakowało wyrażenia # 4 w GROUP BY.
źródło
Dla localhost / wampserver 3 możemy ustawić tryb sql = tryb_użytkownika, aby usunąć ten błąd:
następnie uruchom ponownie wamp lub apache
źródło
Możesz dodać
unique index
dogroup_id
; jeśli jesteś pewien, żegroup_id
jest wyjątkowy.Może rozwiązać twoją sprawę bez zmiany zapytania .
Późna odpowiedź, ale nie została jeszcze wspomniana w odpowiedziach. Może powinien wypełnić wyczerpujące już dostępne odpowiedzi. Przynajmniej rozwiązało to mój przypadek, gdy musiałem podzielić tabelę ze zbyt dużą liczbą pól.
źródło
Jeśli masz ten błąd w Symfony używającym konstruktora zapytań doktrynowych i jeśli błąd ten jest spowodowany przez orderBy :
Zwróć uwagę
select
na kolumnę, którą chceszgroupBy
, i użyjaddGroupBy
zamiastgroupBy
:Działa na Symfony3 -
źródło
Przepraszamy za nieużywanie dokładnego kodu SQL
Użyłem tego zapytania, aby pokonać ostrzeżenie MySQL.
zwróć uwagę na klucz dla mnie
źródło