PostgreSQL JOINTURE EXTERNE GAUCHE de la syntaxe de requête
Permet de dire que j'ai un table1
:
id name
-------------
1 "one"
2 "two"
3 "three"
Et un table2
avec une clé étrangère pour la première:
id tbl1_fk option value
-------------------------------
1 1 1 1
2 2 1 1
3 1 2 1
4 3 2 1
Maintenant, j'ai envie de l'avoir comme résultat de la requête:
table1.id | table1.name | option | value
-------------------------------------
1 "one" 1 1
2 "two" 1 1
3 "three"
1 "one" 2 1
2 "two"
3 "three" 2 1
Comment puis-je y parvenir?
J'ai déjà essayé:
SELECT
table1.id,
table1.name,
table2.option,
table2.value
FROM table1 AS table1
LEFT outer JOIN table2 AS table2 ON table1.id = table2.tbl1fk
mais le résultat semble omettre la valeur null dans un cadre enchanteur:
1 "one" 1 1
2 "two" 1 1
1 "one" 2 1
3 "three" 2 1
RÉSOLU: grâce à Mahmoud Gamal: (avec le GROUPE)
Résolu avec cette requête
SELECT
t1.id,
t1.name,
t2.option,
t2.value
FROM
(
SELECT t1.id, t1.name, t2.option
FROM table1 AS t1
CROSS JOIN table2 AS t2
) AS t1
LEFT JOIN table2 AS t2 ON t1.id = t2.tbl1fk
AND t1.option = t2.option
group by t1.id, t1.name, t2.option, t2.value
ORDER BY t1.id, t1.name
En fait, votre solution de ne fonctionne pas. Pensez à l'extension des cas de test dans ce SQLfiddle.
OriginalL'auteur kosta | 2013-03-25
Vous devez vous connecter pour publier un commentaire.
Vous devez utiliser
CROSS JOIN
pour obtenir toutes les combinaisons possibles dename
de la première table avec leoption
de la deuxième table. PuisLEFT JOIN
ces combinaison avec la deuxième table. Quelque chose comme:SQL Violon Démo
Fonctionne presque, mais pas tout à fait. Voir la SQLfiddle dans mon commentaire ci-dessus.
Semble cher avec la croix-jointures si les tables concernées sont de grands--aucun moyen de contourner cela?
exécutez le
EXPLAIN
de l'instruction sur votre requêteEXPLAIN SELECT ...the rest of your query
et voir si toutes les optimisations qui peut être fait. Également veiller à ce que les index sont correctement définis sur votre table.JOIN fonctionne bien comme prévu, le point est que; dans l'échantillon de données de l'utilisateur affiché de toutes les lignes dans les premiers tableaux ont des lignes correspondantes dans l'autre table
table2
, donc il n'y a pasnull
valeurs à cause de cela. Mais si vous supprimez (par exemple) la dernière ligne de latable2
, vous obtiendrez une des valeurs null , puisque le nomthree
a pas de lignes correspondantes dans la seconde table. Mais ce n'est pas ce que l'OP veut, si vous regardez le résultat souhaité, il veut sélectionner tous les noms de latable1
avec toutes les combinaisons possibles à partir de latable2
.OriginalL'auteur Mahmoud Gamal
Version Simple: option = groupe
Il n'est pas spécifié dans le Q, mais il semble que l'option est censée définir un groupe en quelque sorte. Dans ce cas, la requête peut être simplement:
Ou, si les options ne sont pas numérotés dans l'ordre, en commençant avec
1
:Retourne:
CROSS JOIN
et le grandGROUP BY
.grp
) par set.Plus complexe: groupe indiqué par la séquence de lignes
Résultat:
-> SQLfiddle pour les deux.
Comment?
Expliquant le complexe de la version ...
Chaque set est a commencé avec un
tbl1_fk
<= le dernier. J'ai vérifier avec le la fenêtre de la fonctiongal()
. Pour couvrir les cas de coin de la première ligne (pas de ligne précédente) j'ai la la plus grande possible integer2147483647
la valeur par défaut pourlag()
.Avec
count()
globale de la fenêtre de fonction que j'ai ajouter le nombre à chaque ligne, de manière efficace en formant le numéro de groupegrp
.J'ai pu obtenir une instance unique pour chaque groupe:
Mais il est plus rapide de récupérer le maximum et emploient la chouette
generate_series()
pour la réduction de laCROSS JOIN
.Ce
CROSS JOIN
produit exactement les lignes dont nous avons besoin sans surplus. Évite la nécessité d'une plus tardGROUP BY
.LEFT JOIN t2
, à l'aide degrp
en plus detbl1_fk
pour le rendre distinctes.De tri de n'importe quelle façon - ce qui est possible maintenant avec un numéro de groupe.
OriginalL'auteur Erwin Brandstetter
essayer cette
j'ai mis à jour mon code.voir une fois
même résultat, même avec une JOINTURE, même avec une JOINTURE EXTERNE GAUCHE 🙁 je suis en utilisant postgreSQL 9.1
OriginalL'auteur PSR
C'est assez:
select * from table1 left join table2 sur la table1.id=table2.tbl1_fk ;
OriginalL'auteur user1389698