2009-07-07 14 views
0

J'essaie d'éviter d'utiliser des requêtes dans les boucles while. Par conséquent, je suis arrivé à la conclusion que je devrais utiliser une jointure croisée. Prenons un exemple:Croix externe Join?

SELECT * FROM products 
CROSS JOIN images USING (imgId) 
CROSS JOIN productcolors ON colorsId = colorId 
WHERE productId = 1 

doit retourner deux rangées (structure de la table ci-dessous):

imgId | productId | colorId | imgSrc  | colorName 
1  1   1   img1_0.png copper 

imgId | productId | colorId | imgSrc  | colorName 
1  1   1   img1_0.png slate 

et quand productId = 2 doit retourner une rangée:

imgId | productId | colorId | imgSrc  | colorName 
null 2   -1   null   null 

Le tableau d'images contient plusieurs enregistrements avec le même imgId, la même chose s'applique pour les couleurs de produit où plusieurs colorIds pourraient/auront la même valeur. Il peut également n'y avoir aucun enregistrement dans la table des images (si imgId par exemple = -1 dans la table des produits). Cela voudrait dire qu'un produit n'a pas de couleurs. Maintenant, lorsque je crée cette requête et que la table images ou productcolors ne contient aucun enregistrement pour imgId ou colorId, la requête ne renvoie aucun résultat. Je voudrais que les champs de la ligne contiennent des valeurs nulles au lieu de ne rien retourner, se comportant comme une jointure externe gauche et une jointure croisée.

Peut-être que je devrais avoir des requêtes dans mon whileloop à la place? Y a-t-il peut-être un autre moyen d'aborder ce problème?

EDIT: Mes tables

products: 
productId | colorsId | imgId 
1   1   1 
2   -1   -1  //product 2 has no images nor colors 

productcolors: 
colorId | colorName 
1   copper 
1   slate 

images: 
imgId | imgSrc 
1  img1_0.png 
+0

Un échantillon des données que vous souhaitez voir serait utile. – paulwhit

+1

Il est difficile de comprendre ce que vous voulez. Je pense que votre modèle de données est un peu erroné. Et même si ce n'est pas le cas, les jointures croisées ne sont pas à 90% ce que vous voulez. Pensez à poster les schémas pour vos tables avant de continuer à étudier les jointures croisées. Encore une fois, la plupart ne sont probablement pas ce que vous voulez. –

+0

"se comporte comme une jointure externe gauche." Alors pourquoi ne pas utiliser une jointure externe gauche? –

Répondre

3

Je recommande rééquiper les couleurs de produits ainsi sont stockés, la transformer en quelque chose comme ceci:

products: 
productId | imgId | productName 
1   1  rock 
2   null roll 

productcolors: 
productId | colorId 
1   1 
1   2 

colors: 
colorId | colorName 
1   copper 
2   slate 

images: 
imgId | imgSrc 
1  img1_0.png 

productcolors ci-dessus est un nombre à plusieurs joindre la table. Ceci suppose également que vous avez seulement une image pour chaque produit, et laisse cette table seule.

Pour obtenir une liste de produits, y compris leurs couleurs:

SELECT p.productId, p.productName, c.colorId, c.colorName, i.imgSrc 
FROM products p 
LEFT JOIN images i USING (imgId) 
LEFT JOIN productcolors pc USING(productId) 
LEFT JOIN color c USING(colorId) 
+0

Merci! Je suppose que je pourrais fondamentalement faire la même chose pour les images. – Baversjo