Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Fehler:SELECT-Liste ist nicht in GROUP BY-Klausel

Wenn Sie GROUP BY verwenden, können Sie Ausdrücke in Ihrer Auswahlliste nur dann verwenden, wenn sie einen einzigen Wert pro Gruppe haben. Andernfalls erhalten Sie mehrdeutige Abfrageergebnisse.

In Ihrem Fall glaubt MySQL, dass s.status kann mehrere Werte pro Gruppe haben. Beispielsweise gruppieren Sie nach p.products_id sondern s.status ist eine Spalte in einer anderen Tabelle specials , möglicherweise in einer 1:n-Beziehung mit der Tabelle products . Es können also mehrere Zeilen in specials vorhanden sein mit derselben products_id , aber unterschiedliche Werte für status . Wenn ja, welcher Wert für status sollte die Abfrage verwenden? Es ist mehrdeutig.

Möglicherweise beschränken Sie in Ihren Daten die Zeilen so, dass Sie nur eine Zeile in specials haben für jede Zeile in products . Aber MySQL kann diese Annahme nicht treffen.

Mit MySQL 5.6 und früheren Versionen können Sie solche mehrdeutigen Abfragen schreiben und darauf vertrauen, dass Sie wissen, was Sie tun. Aber MySQL 5.7 ermöglicht standardmäßig eine strengere Durchsetzung (dies kann weniger streng gemacht werden, um sich wie frühere Versionen zu verhalten).

Die Lösung besteht darin, diese Regel zu befolgen:Jede Spalte in Ihrer Auswahlliste muss in einen von drei Fällen fallen:

  • Die Spalte befindet sich in einer Aggregatfunktion wie COUNT(), SUM(), MIN, MAX(), AVERAGE() oder GROUP_CONCAT().
  • Die Spalte ist eine der in GROUP BY benannten Spalte(n). Klausel.
  • Die Spalte ist funktional abhängig von der/den im GROUP BY benannten Spalte(n). Klausel.

Für weitere Erklärungen lesen Sie diesen exzellenten Blog:GRUPPE NACH Mythen entlarven

Zu Ihrem Kommentar kann ich nur Vermutungen anstellen, da Sie Ihre Tabellendefinitionen nicht gepostet haben.

Ich vermute, dass products_description und manufacturers sind funktional abhängig von products , also ist es in Ordnung, sie so aufzulisten, wie sie in der Auswahlliste sind. Aber diese Annahme ist möglicherweise nicht korrekt, ich kenne Ihr Schema nicht.

Wie auch immer, der Fehler über s.status sollte mit einer Aggregatfunktion aufgelöst werden. Ich verwende MAX() als Beispiel.

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;

Ich habe auch Ihre Verknüpfungen auf die richtige Weise umgeschrieben. Joins im Kommastil sollten vermieden werden.