1
votes

J'ai besoin de champs vides dans une requête multitable - FERMÉ

Cela devrait être facile pour vous, mais je suis perdu ici:

J'ai une base de données avec 4 tables: commandes, clients, produits, commandes_produits

J'ai besoin de récupérer tous les clients, avec toutes leurs commandes, y compris celles qui n'ont pas de commande.

Je ne reçois que les onces qui ont passé une commande. Le pauvre vieux "Nick" dans le tableau Clients n'apparaîtra pas.

Qu'est-ce que je fais de mal ici?

SELECT c.name clientname, o.id orderID, GROUP_CONCAT(p.name) productNAMEs, 
GROUP_CONCAT(p.id) productIDs
FROM clients c
LEFT JOIN  orders o ON c.id = o.client_id
LEFT  JOIN  orders_products op ON o.id = op.order_id
LEFT  JOIN  products p  ON p.id = op.product_id  
WHERE c.status = 1
GROUP BY c.name

Voir les définitions du tableau ici: https://www.db-fiddle.com/f/bTRSLfYTa19S2EpE2zKwUvUv7

Merci pour votre temps.

MISE À JOUR: @scaisedge a trouvé une réponse qui inclut les clients sans commandes:

SELECT c.name clientname, o.id orderID, GROUP_CONCAT(p.name) productNAMEs,
    GROUP_CONCAT(p.id) productIDs
FROM clients c, orders o, orders_products op, products p
WHERE c.id = o.client_id
AND c.status = 1
AND o.id = op.order_id
AND p.id = op.product_id
GROUP BY c.name

Vous pouvez voir les résultats ici: https://www.db-fiddle.com/f / 8bGcQJSbSFmKMUo1tLuZuA / 1

Il semble que ne pas utiliser JOIN soit mon problème.

Merci encore à tous pour votre temps.


1 commentaires

Astuce du jour: utilisez toujours la syntaxe JOIN moderne et explicite. Plus facile à écrire (sans erreur), plus facile à lire et à maintenir, et plus facile à convertir en jointure externe si nécessaire!


3 Réponses :


0
votes

N'utilisez jamais de virgule dans la clause FROM . Utilisez toujours une syntaxe appropriée, explicite, standard JOIN .

De plus, votre GROUP BY doit correspondre au colonnes non agrégées dans le SELECT.

Je ne suis pas sûr si vous avez l'intention de ceci:

SELECT c.name as clientname,      
       GROUP_CONCAT(p.name) as productNAMEs,
       GROUP_CONCAT(p.id) productIDs
FROM clients c left join
     orders o
     on c.id = o.client_id left join
     orders_products op
     on o.id = op.order_id left join
     products p
     on p.id = op.product_id
WHERE c.status = 1
GROUP BY c.name;

Ou: p >

SELECT c.name as clientname, o.id as orderID,        
       GROUP_CONCAT(p.name) as productNAMEs,
       GROUP_CONCAT(p.id) productIDs
FROM clients c left join
     orders o
     on c.id = o.client_id left join
     orders_products op
     on o.id = op.order_id left join
     products p
     on p.id = op.product_id
WHERE c.status = 1
GROUP BY c.name, o.id;


1 commentaires

Merci pour l'aide, j'obtiens une erreur sur le code suggéré: db-fiddle. com / f / gZYKsLPpiKJ9hHveSs57Eq / 1



1
votes

Utilisez la syntaxe de jointure explicite et la jointure gauche pour récupérer également les lignes qui ne correspondent pas à

SELECT c.name clientname, o.id orderID, GROUP_CONCAT(p.name) productNAMEs, 
GROUP_CONCAT(p.id) productIDs
FROM clients c
LEFT JOIN  orders o ON c.id = o.client_id
LEFT  JOIN  orders_products op ON o.id = op.order_id
LEFT  JOIN  products p  ON p.id = op.product_id  
WHERE c.status = 1
GROUP BY c.name


3 commentaires

Je suis un nouvel utilisateur SQL, donc je vais devoir en apprendre davantage sur JOINS :) Mais votre code ne renvoie pas le client "Nick", donc ce n'est pas la solution dont j'ai besoin: db-fiddle.com/f/ujcc7eVvQtB7SPLt6FmBPR/0


@Giannis. réponse mise à jour .. retunr 3 lignes également les valeurs nulles 3rdwit db-fiddle.com/f/ ujcc7eVvQtB7SPLt6FmBPR / 0


Merci, ça marche. Maintenant, je dois mettre la main sur JOINS afin que je puisse comprendre ce qu'ils font :) Merci encore pour votre temps.



1
votes

Je vous recommande d'utiliser les JOIN pour UNIFIER les données des tables. Une clause JOIN est utilisée pour combiner des lignes de deux tables ou plus, en fonction d'une colonne liée entre elles.

https://www.w3schools.com/sql/sql_join.asp

SELECT *
FROM clients LEFT JOIN orders ON clients.id = orders.client_id
     LEFT JOIN orders_products ON clients.id = orders_products.order_id 
     LEFT JOIN products ON products.id = orders_products.product_id
WHERE clients.status = 1;


1 commentaires

Merci pour le lien, je vais le vérifier