SELECT name, price, photo FROM drinks, drinks_photos WHERE drinks.id = drinks_id
yeilds 5 Zeilen (5 Arrays), photo
ist das einzige eindeutige Feld in einer Zeile. name, price
werde wiederholt ( hier fanta-
name, price
dreimal wiederholen ). Wie entferne ich diese Duplikate?
Edit: Ich will name, price
und alles photo
für jedes Getränk.
id name price
1. fanta 5
2. dew 4
id photo drinks_id
1. ./images/fanta-1.jpg 1
2. ./images/fanta-2.jpg 1
3. ./images/fanta-3.jpg 1
4. ./images/dew-1.jpg 2
5. ./images/dew-2.jpg 2
mysql
multiple-tables
NestedWeb
quelle
quelle
Antworten:
Was Sie hier tun, wird als a bezeichnet
JOIN
(obwohl Sie dies implizit tun, weil Sie aus mehreren Tabellen auswählen). Das heißt, wenn Sie keine Bedingungen in Ihre WHERE-Klausel aufgenommen haben, hatten Sie alle Kombinationen dieser Tabellen. Nur mit Ihrer Bedingung beschränken Sie Ihre Verbindung auf die Zeilen, in denen die Getränke-ID übereinstimmt.Es gibt jedoch immer noch X mehrere Zeilen im Ergebnis für jedes Getränk, wenn X Fotos mit dieser bestimmten Getränke-ID vorhanden sind. Ihre Aussage schränkt nicht ein, welche Fotos Sie haben möchten!
Wenn Sie nur eine Zeile pro Getränk möchten, müssen Sie SQL mitteilen, was Sie tun möchten, wenn mehrere Zeilen mit einer bestimmten Getränke-ID vorhanden sind. Dazu benötigen Sie eine Gruppierung und eine Aggregatfunktion . Sie teilen SQL mit, welche Einträge Sie gruppieren möchten (z. B. alle gleichen Drinks_ids), und in SELECT müssen Sie angeben, welche der unterschiedlichen Einträge für jede gruppierte Ergebniszeile verwendet werden sollen. Bei Zahlen kann dies Durchschnitt, Minimum, Maximum sein (um nur einige zu nennen).
In Ihrem Fall sehe ich keinen Sinn darin, die Fotos nach Getränken abzufragen, wenn Sie nur eine Zeile möchten. Sie dachten wahrscheinlich, Sie könnten für jedes Getränk eine Reihe von Fotos in Ihrem Ergebnis haben, aber SQL kann dies nicht. Wenn Sie nur ein Foto möchten und es Ihnen egal ist, welches Sie erhalten, gruppieren Sie es einfach nach der drink_id (um nur eine Zeile pro Getränk zu erhalten):
SELECT name, price, photo FROM drinks, drinks_photos WHERE drinks.id = drinks_id GROUP BY drinks_id
In MySQL haben wir auch GROUP_CONCAT , wenn Sie möchten, dass die Dateinamen zu einer einzigen Zeichenfolge verkettet werden:
SELECT name, price, GROUP_CONCAT(photo, ',') FROM drinks, drinks_photos WHERE drinks.id = drinks_id GROUP BY drinks_id
Dies kann jedoch gefährlich werden, wenn Sie
,
Werte innerhalb des Feldes haben, da Sie diese höchstwahrscheinlich auf der Clientseite erneut aufteilen möchten. Es ist auch keine Standard-SQL-Aggregatfunktion.quelle
GROUP_CONCAT
und es erneut teilen. In relationalen Datenbanken ist dies normalerweise nicht der Fall. Sie sollten die Gruppierung im Programm und nicht in SQL durchführen (erkennen Sie die doppelten IDs und erstellen Sie diese Arrays in Ihrem Programm).GROUP BY
undGROUP_CONTACT
, aber auch weiterhin , wie Sie taten , aber um durchdrinks.id
. Auf diese Weise können Sie die Ergebnismenge durchlaufen und Bilder auf der Clientseite in Arrays sammeln.Hier haben Sie die doppelten Werte für Name und Preis. Und IDs sind in der Tabelle drink_photos doppelt vorhanden. Sie können sie auf keinen Fall vermeiden. Auch was genau möchten Sie für die Ausgabe?
quelle
Um Duplikate zu entfernen, können Sie nach gruppieren
drinks.id
. Auf diese Weise erhalten Sie jedoch nur ein Foto für jedes Fotodrinks.id
(welches Foto Sie erhalten, hängt von der datenbankinternen Implementierung ab).Obwohl es nicht dokumentiert ist, erhalten Sie im Fall von MySQL das Foto mit dem niedrigsten Wert
id
(meiner Erfahrung nach habe ich noch nie ein anderes Verhalten gesehen).SELECT name, price, photo FROM drinks, drinks_photos WHERE drinks.id = drinks_id GROUP BY drinks.id
quelle
GROUP BY
(das ist kein SQL-Standard) immer noch nicht einverstanden bin, ohne zu erklären, warum es funktioniert und wie esphoto
für jedes Getränk einen halbzufälligen Wert zurückgibt. (Das "erste" in der Phrase "Sie erhalten das erste Foto" ist einfach falsch).photo
mit der niedrigsten ID zurück. Ich habe noch nie ein anderes Verhalten in MySQL gesehen (obwohl es nicht dokumentiert ist). Ich habe eine Notiz zu meinem Beitrag hinzugefügt