2017-09-11 2 views
0

J'ai trois tables. Table Cust a un champ custID, plus diverses autres valeurs (nom, adresse, etc.)Comment joindre des tables lorsqu'il y a des doublons dans la table de droite

La liste de tables a un ID de colonne unique. Chaque ID est un ID de dépôt dans la table Cust. Éditer: le but de ceci est de filtrer les enregistrements, en limitant les résultats à ceux où le CustID apparaît dans la table de liste.

Les trois tables sont indexées.

Table Trans a un champ TransactionID, un champ Cust qui est titulaire d'un numéro de client, et d'autres domaines transaction

Edit: je l'ai mentionné que, dans certains cas, il n'y aura pas relevé de transaction. Dans ce cas, je veux une ligne d'informations client avec les champs de transaction null ou vide.

Je veux une requête pour retourner cust et ID de transaction pour chaque ID dans la table de liste. S'il y a plus d'une rangée correspondante dans la table des transactions, je veux que chacune d'elles soit incluse avec les informations de la contrepartie. Donc, si les tableaux ressemblent à ceci:

Cust 
ID  Name 
01  John 
02  Mary 
03  Mike 
04  Jane 
05  Sue 
06  Frank 

    List 
ID 
01 
03 
05 
06 

     Transact 
TransID CustId Msg 
21  01  There 
22  01  is 
23  02  a 
24  03  tide 
25  04  in 
26  04  the 
27  05  affairs 
28  05  of 
29  05  men 

Je veux que le jeu de résultats à être:

CustID Name TransID Msg 
01  John 21  There 
01  John 22  is 
03  Mike 24  tide 
05  Sue 27  affairs 
05  Sue 28  of 
05  Sue 29  men 
06  Frank --  -- 

(Où - représente NULL ou BLANK)

Il est évident que les tableaux réels sont beaucoup plus grandes (millions de lignes), mais cela affiche le motif, une ligne pour chaque élément de la table Transactions correspondant à l'un des éléments de la table Liste, avec les champs correspondants de la table Cust. s'il n'y a pas de transaction correspondante, une ligne d'informations client de chaque ID dans la table Liste. CustID est unique dans les tables Cust et List, mais pas dans la table des transactions.

Cela doit fonctionner sur n'importe quelle version du serveur SQL à partir de 2005, si cela est important.

Des suggestions?

+0

Je ne suis pas tout à fait sûr de ce que la question semble être, comme une jointure ramènera tous les enregistrements qui correspondent à la clause de jointure. En outre, la table de liste ne semble pas appartenir au mélange, à moins qu'il y ait un but que vous n'avez pas mentionné. Vous pouvez rejoindre directement de la table cust à la transaction. Veuillez mettre à jour votre question et ajouter la requête que vous avez essayée. Si vous obtenez des résultats incorrects, nous pouvons essayer de vous aider avec cela. – Eli

+0

La table de liste est utilisée pour restreindre les ID retournés. Dans l'exemple de jouet ci-dessus, il empêche les résultats affichés pour les valeurs CustID 2 ou 4. Dans mon système de test, il réduit des dizaines de milliers d'enregistrements à quelques centaines, et sur un site de Cleint, il réduit des millions d'enregistrements dans tables de transaction à 1-2 mille résultats –

+0

Dans un système approprié (clés étrangères, index), vous devriez être en mesure de fonctionner correctement sans cette table de liste. Qu'avez-vous essayé de faire fonctionner cela? – Eli

Répondre

0

À moins que je me manque quelque chose, cela est tout ce que vous devez faire:

Select T.CustID, C.Name, T.TransID, T.Msg 
From  Transact T 
Join  Cust  C On C.Id = T.CustId 
Join  List  L On L.Id = C.Id 
Order By T.CustID, T.TransID 
0
;with cust (id, name) as 
(
    select 1, 'John' union all 
    select 2, 'Mary' union all 
    select 3, 'Mike' union all 
    select 4, 'Jane' union all 
    select 5, 'Sue' 
), list (id) as 
(
    select 1 union all 
    select 3 union all 
    select 5 
), transact (TransId, CustId, Msg) as 
(
    select 21, 1, 'There ' 
    union all select 22, 1, 'is' 
    union all select 23, 2, 'a' 
    union all select 24, 3, 'tide' 
    union all select 25, 4, 'in' 
    union all select 26, 4, 'the' 
    union all select 27, 5, 'affairs' 
    union all select 28, 5, 'of' 
    union all select 29, 5, 'men' 
) 
select 
    CustId = c.id, 
    Name = c.Name, 
    TransId = t.TransId, 
    Msg = t.Msg 
from cust c 
inner join list l 
    on c.id = l.id 
inner join transact t 
    on l.id = t.custid 

rendements:

CustId  Name TransId  Msg 
----------- ---- ----------- ------- 
1   John 21   There 
1   John 22   is 
3   Mike 24   tide 
5   Sue 27   affairs 
5   Sue 28   of 
5   Sue 29   men 
+0

Cela fonctionne presque, il ne me donne pas la réponse quand un ID inclus dans la liste et les tables cust n'a pas de ligne trans correspondant.J'ai omis de mentionner que dans mon message initial –

+0

@DavidSiegel s'il vous plaît mettre à jour votre message pour inclure cela - la plupart des lecteurs ne le trouveront pas ici – Eli

+1

Modifier la join pour «transact» pour être une «jointure externe gauche». Cela inclura toutes les lignes cust/list, qu'il y ait ou non des transactions – Xedni