2010-10-19 2 views
1

J'ai deux tables pour une boutique en ligne:Comment choisir parmi deux tables dans MySQL même si toutes les lignes d'une table n'ont pas de corespondents dans l'autre?

  • une pour les catégories: id, titre
  • un pour les produits: id, ownerid, le titre, le prix (ownerid est l'identifiant de la catégorie parente)

Je veux sélectionner toutes les catégories et également sélectionner le prix minimum et maximum dans chaque, d'où la requête suivante:

SELECT 
sc.*, MIN(s.price) AS minp, MAX(s.price) AS maxp 
FROM 
categories AS sc, products AS s 
WHERE s.ownerid=sc.id 
GROUP BY sc.id 

Il wo rks à peu près comme prévu, à la seule exception que si une catégorie ne contient aucun produit, elle n'est pas sélectionnée. Bien que cela semble logique puisque je demande "s.ownerid = sc.id", je ne connais pas assez SQL pour le faire fonctionner comme prévu. J'ai besoin de toutes les catégories et pour celles qui n'ont pas de produits, minp et maxp devraient être 0.

Un conseil? Merci.

Répondre

2

Pour ce faire, vous avez besoin d'une jointure externe. En passant, la façon dont vous écrivez votre requête avec une jointure implicite est obsolète et n'est plus recommandée. L'utilisation du mot clé JOIN est recommandée. Cela facilite également la modification d'une jointure interne en une jointure externe.

FROM categories AS sc 
LEFT JOIN products AS s 
ON s.ownerid=sc.id 

Pour revenir 0 au lieu de NULL utiliser IFNULL(..., 0). La requête entière devient:

SELECT 
    sc.*, 
    IFNULL(MIN(s.price), 0) AS minp, 
    IFNULL(MAX(s.price), 0) AS maxp 
FROM categories AS sc 
LEFT JOIN products AS s 
ON s.ownerid = sc.id 
GROUP BY sc.id 

Vous pouvez également envisager de s'il serait préférable de renvoyer la valeur NULL par défaut au lieu de 0 pour les catégories qui ont aucun produit.

+0

Merci, et merci à tous pour votre aide – pandronic

0

Vous voulez faire une jointure gauche:

SELECT 
sc.*, MIN(s.price) AS minp, MAX(s.price) AS maxp 
FROM 
categories AS sc 
LEFT JOIN products AS s on s.ownerid=sc.id 
GROUP BY sc.id 

Lorsque vous utilisez une jointure gauche, vous obtenez les données de la table à la gauche de la gauche rejoindre (ici les catégories) et à droite si existe.

0

Je pense que ce que vous voulez est LEFT JOIN, par exemple:

SELECT
sc.*, MIN(s.price) AS minp, MAX(s.price) AS maxp
FROM categories sc
LEFT JOIN products s ON s.ownerid = sc.id
GROUP BY sc.id

2

Que diriez-vous d'un LEFT JOIN (W3Schools)?

SELECT 
sc.*, MIN(s.price) AS minp, MAX(s.price) AS maxp 
FROM 
categories AS sc 
LEFT JOIN products AS s 
ON s.ownerid=sc.id 
GROUP BY sc.id 
0

Essayez d'utiliser LEFT JOIN:

SELECT sc.*, MIN(s.price) AS minp, MAX(s.price) AS maxp 
FROM categories AS sc 
LEFT JOIN products AS s ON s.ownerid = sc.id 
GROUP BY sc.id 

Cependant, en utilisant le produit cartésien est pas la meilleure solution, dans le doute. La plupart des moteurs devraient être capables de l'optimiser "à l'écart", mais les jointures sont aussi beaucoup plus intuitives dans la plupart des cas - et plus rapides, dans le doute.

Questions connexes