J'ai trois tables dont j'ai besoin d'être jointes dans une seule table de sortie mais aucune jointure ou virgule ne semble produire la sortie souhaitée
la table est
e1 g1 s1 b1
e1 g1 s1 b2
e1 g1 s2 b1
e1 g1 s2 b2
le les données ressemblent à ceci
E | G | S | B
e1| g1| s1| b1
e2| g2| s2| b2
la sortie que je veux est
e1 g1 | e1 s1 | e1 b1
e2 g2 | e2 s2 | e2 b2
select e1,g,s,b from
(select e as e1, m as g from table x where m=g),
(select e as e2, m as s from table x where m=s),
(select e as e3, m as b from table x where m=b)
where e1=e2 AND e2=e3;
mais j'obtiens le résultat de la multiplication p >
E G | E S | E B
J'ai essayé d'utiliser la jointure naturelle au lieu de la virgule, mais je n'obtiens pas le résultat souhaité, je ne comprends pas le problème qu'une jointure naturelle devrait facilement résoudre le problème, n'est-ce pas?
3 Réponses :
utilisez une requête corrélée :
select e.col1 E,e.col2 G,(select s.col2 from s where s.col1=e.col1 ) S, (select b.col2 from b where b.col1=e.col1 ) B from e;
Un simple JOIN ferait:
create table e (e varchar(2), g varchar(2));
insert into e (e, g) values ('e1', 'g1'), ('e2', 'g2');
create table s (e varchar(2), s varchar(2));
insert into s (e, s) values ('e1', 's1'), ('e2', 's2');
create table b (e varchar(2), b varchar(2));
insert into b (e, b) values ('e1', 'b1'), ('e2', 'b2');
Résultat (voir SQL Fiddle ):
e g s b -- -- -- -- e1 g1 s1 b1 e2 g2 s2 b2
Pour référence, voici les données que j'ai utilisées:
select e.e, e.g, s.s, b.b from e join s on s.e = e.e join b on b.e = e.e
Une dernière remarque : en règle générale, essayez d'éviter les jointures naturelles. Ils sont obscurs et sujets aux insectes. Le pire de tout, ils ne survivent pas bien après un certain temps lorsque la base de données change [inexorablement].
"Ils sont obscurs et sujets aux bogues" - avez-vous des citations pour ces affirmations?
@onedaywhen: parce qu'ils s'appuient sur des noms de colonnes plutôt que sur des clés étrangères déclarées - et quelles colonnes il choisit n'est pas si évidente. Pouvez-vous me dire quelles colonnes de jointure sont utilisées dans cet exemple
@a_horse_with_no_name: homme de paille: vous avez créé un schéma avec des noms d'éléments de données en double. Pourquoi ne pas utiliser le dictionnaire de données NHS comme meilleur exemple? ( datadictionary.nhs.uk/data_dictionary/data_field_notes/… )
@a_horse_with_no_name: C'est ainsi que la jointure naturelle fonctionne par conception . Ils ne sont peut-être pas à votre goût, mais je posais des questions sur l'obscurité et la bugginess. P.S. aucun type de jointure (ni aucun autre opérateur relationnel SQL) ne dépend des clés étrangères déclarées, vous confondez SQL DDL et SQL DML.
@onedaywhen: Je sais qu'aucun type de jointure n'utilise des clés étrangères déclarées et je sais que c'est ainsi que le standard SQL a défini ce type de jointure. De mon point de vue, la seule façon dont la jointure naturelle aurait aurait du sens si elle utilisait des contraintes FK. Utiliser une jointure naturelle dans le code de production est tout simplement un problème. Les noms de mon exemple (inventé) ne sont cependant pas si exagérés. L'utilisation de id comme nom de colonne PK peut être discutable. Mais des noms de colonnes comme created_at (ou name ou due_date ) peuvent effectivement exister dans plus d'une table et alors vous êtes b > en difficulté si vous utilisez une jointure naturelle
@a_horse_with_no_name: Je trouve name tout aussi discutable. Cela n'a rien à voir avec le SQL standard et tout à voir avec la conception du langage. Vos éléments de données created_at mélangent des données et des métadonnées (j'utiliserais un schéma différent pour un tel audit). Je comprends que vous n'aimez pas la jointure naturelle mais cela n'équivaut pas à des «bogues».
Un simple NATURAL JOIN fonctionne bien:
WITH e1 AS ( SELECT e, g FROM e ),
s1 AS ( SELECT e, s FROM s ),
b1 AS ( SELECT e, b FROM b )
SELECT e, g, s, b
FROM e1 NATURAL JOIN s1 NATURAL JOIN b1;
Résultat (voir SQL Fiddle ):
e g s b -- -- -- -- e1 g1 s1 b1 e2 g2 s2 b2
Une dernière remarque : la jointure naturelle est uniquement le type de jointure dont vous avez besoin et présente des avantages par rapport aux jointures «héritées», par exemple aucune colonne en double signifie que vous n'avez pas besoin de variables de plage pour les résoudre.
Le produit SQL de votre choix contient-il des bogues? Tous les logiciels le font; si cela vous concerne, essayez un autre produit SQL.
Si vous craignez que des modifications incontrôlées du schéma affectent la sémantique de votre requête à l'avenir, il existe différentes manières de coder défensivement, par exemple en utilisant des CTE:
SELECT e, g, s, b FROM e NATURAL JOIN s NATURAL JOIN b;
La jointure naturelle n'est certainement pas le "seul type de jointure dont vous avez besoin" - en fait, vous devriez éviter la jointure naturelle comme la peste.
@a_horse_with_no_name: au contraire, depuis que je suis passé exclusivement à jointure naturelle je n'ai jamais eu besoin d'un autre type de jointure.
On ne sait pas à quoi
le tableaufait réellement référence. Il ne peut pas s'agir d'une seule table, car les noms de colonnes se répètent. Alors c'est quoi?vos tables sont très imprévisibles !!!
désolé les tables sont
je suis désolé pour uncarity, j'ai un seul tableau avec la colonne M, qui a des valeurs G, S, B ou N je veux sélectionner les valeurs E correspondant à G les valeurs correspondant à S et B chacune dans une colonne
En règle générale, essayez d'éviter les jointures naturelles. Ils sont obscurs et sujets aux insectes. Le pire de tout, ils ne survivent pas bien après un certain temps lorsque la base de données change [inexorablement].
Je suis totalement perdu. Vos sous-requêtes semblent suggérer que vous n'avez qu'une seule table. Mais vos données et votre texte suggèrent plusieurs tableaux.