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.