Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Błąd MySQL:lista SELECT nie znajduje się w klauzuli GROUP BY

Korzystając z funkcji GROUP BY, można używać wyrażeń z listy wyboru tylko wtedy, gdy mają one jedną wartość na grupę. W przeciwnym razie otrzymasz niejednoznaczne wyniki zapytania.

W twoim przypadku MySQL uważa, że ​​s.status może mieć wiele wartości na grupę. Na przykład grupujesz według p.products_id ale s.status jest kolumną w innej tabeli specials , być może w relacji jeden-do-wielu z tabelą products . Więc może być wiele wierszy w specials z tym samym products_id , ale inne wartości dla status . Jeśli tak jest, jaka wartość dla status należy użyć zapytania? To niejednoznaczne.

W swoich danych może się zdarzyć, że ograniczysz wiersze tak, że masz tylko jeden wiersz w specials dla każdego wiersza w products . Ale MySQL nie może przyjąć takiego założenia.

MySQL 5.6 i wcześniejsze pozwalają pisać takie niejednoznaczne zapytania, ufając, że wiesz, co robisz. Ale MySQL 5.7 domyślnie umożliwia bardziej rygorystyczne egzekwowanie (może to być mniej rygorystyczne, aby zachowywać się jak wcześniejsze wersje).

Rozwiązaniem jest przestrzeganie tej zasady:każda kolumna na liście wyboru musi należeć do jednego z trzech przypadków:

  • Kolumna znajduje się wewnątrz funkcji agregującej, takiej jak COUNT(), SUM(), MIN, MAX(), AVERAGE() lub GROUP_CONCAT().
  • Kolumna jest jedną z kolumn nazwanych w GROUP BY klauzula.
  • Kolumna jest funkcjonalnie zależna od kolumn nazwanych w GROUP BY klauzula.

Aby uzyskać więcej wyjaśnień, przeczytaj ten wspaniały blog:Obalanie GROUP BY mity

Odnieś się do twojego komentarza, mogę tylko zgadywać, ponieważ nie opublikowałeś definicji tabeli.

Domyślam się, że products_description i manufacturers są funkcjonalnie zależne od products , więc można je wymienić tak, jak na liście wyboru. Ale to założenie może nie być poprawne, nie znam twojego schematu.

W każdym razie błąd dotyczący s.status należy rozwiązać za pomocą funkcji agregującej. Używam MAX() jako przykład.

SELECT p.*,
pd.*,
m.*,
MAX(IF(s.status, s.specials_new_products_price, NULL)) 
  AS specials_new_products_price,
MAX(IF(s.status, s.specials_new_products_price, p.products_price)) 
  AS final_price
FROM products p 
LEFT OUTER JOIN specials s ON p.products_id = s.products_id  
INNER JOIN manufacturers m ON p.manufacturers_id = m.manufacturers_id
INNER JOIN products_description pd ON p.products_id = pd.products_id
INNER JOIN products_to_categories p2c ON p.products_id = p2c.products_id
INNER JOIN categories c ON p2c.categories_id = c.categories_id
WHERE p.products_view = 1  
AND p.products_status = 1
AND p.products_archive = 0
AND c.virtual_categories = 0
AND pd.language_id = 1
GROUP BY p.products_id;

Przepisałem również twoje złączenia we właściwy sposób. Należy unikać złączeń w stylu przecinków.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zoptymalizować wydajność COUNT(*) w InnoDB za pomocą index

  2. Golang ORDER BY problem z MySql

  3. Zapytanie MySQL - uzyskiwanie brakujących rekordów podczas korzystania z grupowania

  4. Zamień ciąg znaków MySQL

  5. W jaki sposób fora pokazują nieprzeczytane tematy?