web-dev-qa-db-fra.com

SELECT * FROM plusieurs tables. MySQL

SELECT name, price, photo FROM drinks, drinks_photos WHERE drinks.id = drinks_id

yeilds 5 rangées (5 tableaux), photo est le seul champ unique d’une rangée. name, price être répété ( ici, fanta-name, price répéter 3 fois . ) Comment puis-je me débarrasser de ces doublons?

Edit: Je veux name, price et tout photo pour chaque boisson.

 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
64
NestedWeb

Ce que vous faites ici est appelé JOIN (bien que vous le fassiez de manière implicite, car vous sélectionnez parmi plusieurs tables). Cela signifie que si vous n'avez posé aucune condition dans votre clause WHERE, vous avez toutes les combinaisons de ces tables. Seulement avec votre condition, vous limitez votre participation aux lignes où l'identifiant de boisson correspond.

Mais il y a toujours X rangées multiples dans le résultat pour chaque boisson, s'il y a X photos avec ce drinks_id particulier. Votre relevé ne limite pas la photo (s) que vous souhaitez avoir!

Si vous ne voulez qu'une ligne par boisson, vous devez indiquer à SQL ce que vous voulez faire s'il y a plusieurs lignes avec un drink_id particulier. Pour cela, vous avez besoin d'un groupement et d'un fonction d'agrégat . Vous indiquez à SQL les entrées que vous souhaitez regrouper (par exemple, toutes les boissons drinks égales) et, dans le SELECT, vous devez indiquer les entrées distinctes pour chaque ligne de résultat groupée à prendre. Pour les nombres, cela peut être moyen, minimum, maximum (pour en nommer quelques uns).

Dans votre cas, je ne vois pas le bon sens de demander des boissons aux photos si vous ne voulez qu'une rangée. Vous pensiez probablement que vous pourriez avoir un tableau de photos dans chaque résultat, mais SQL ne peut le faire. Si vous voulez seulement une photo et vous ne vous souciez pas de savoir ce que vous obtiendrez, groupez-le simplement par drinks_id (pour avoir un seul rang par boisson):

SELECT name, price, photo
FROM drinks, drinks_photos
WHERE drinks.id = drinks_id 
GROUP BY drinks_id
name     price   photo
fanta    5       ./images/fanta-1.jpg
dew      4       ./images/dew-1.jpg

Dans MySQL, nous avons également GROUP_CONCAT , si vous souhaitez que les noms de fichiers soient concaténés dans une seule chaîne:

SELECT name, price, GROUP_CONCAT(photo, ',')
FROM drinks, drinks_photos
WHERE drinks.id = drinks_id 
GROUP BY drinks_id
name     price   photo
fanta    5       ./images/fanta-1.jpg,./images/fanta-2.jpg,./images/fanta-3.jpg
dew      4       ./images/dew-1.jpg,./images/dew-2.jpg

Cependant, cela peut devenir dangereux si vous avez , dans les valeurs du champ, car vous souhaiterez probablement le scinder à nouveau du côté client. Ce n'est pas non plus une fonction d'agrégation SQL standard.

92
leemes

Vous aurez les valeurs en double pour le nom et le prix ici. Et les identifiants sont en double dans la table drinks_photos. Il n’ya aucun moyen de les éviter.

3
AnandPhadke

Afin de supprimer les doublons, vous pouvez grouper par drinks.id. Mais de cette façon, vous obtiendrez une seule photo pour chaque drinks.id (la photo que vous obtiendrez dépend de la mise en œuvre interne de la base de données).

Bien que ce ne soit pas documenté, dans le cas de MySQL, vous obtiendrez la photo avec le plus bas id (dans mon expérience, je n’ai jamais vu d’autres comportements).

SELECT name, price, photo 
FROM drinks, drinks_photos 
WHERE drinks.id = drinks_id
GROUP BY drinks.id
2
bhovhannes