2010-03-15 6 views
0

Ceci est une question similaire à une autre question que j'ai publiée here mais est un peu différente. J'essaie d'obtenir une liste de toutes les instances d'utilisateurs existants mutuels et non mutuels. Ce que je veux dire, c'est que le résultat renvoyé par la requête retournera une liste d'utilisateurs avec leur collègue. Il est similaire à la question here, mais la différence est que les utilisateurs non mutuels seront retournés aussi et sans la duplicité des utilisateurs mutuellement existants retournent dans la liste (voir l'image ci-dessous dans l'ordre simplifier tout cela).

Je pris la réponse originale de Thomas (Thanx à nouveau Thomas)
Select D1.u_username, U1.Permission, U1.Grade, D1.f_username, U2.Permission, U2.Grade
from tblDynamicUserList As D1
    Join tblDynamicUserList As D2
        On D2.u_username = D1.f_username
            And D2.f_username = D1.u_username
    Join tblUsers As U1
        On U1.u_username = D1.u_username
    Join tblUsers As U2
        On U2.u_username = D2.u_username

et après plusieurs essais j'ai commenté 2 lignes (ci-dessous).
Les résultats retournés sont ce que j'essaie d'accomplir, comme décrit au début de cette question, à l'exception de la "duplicité" renvoyée par les utilisateurs mutuellement existants dans la table.
Comment puis-je éliminer cette duplicité?

Select D1.u_username, U1.Permission, U1.Grade, D1.f_username, U2.Permission, U2.Grade
from tblDynamicUserList As D1
    Join tblDynamicUserList As D2
        On D2.u_username = D1.f_username
            /* And D2.f_username = D1.u_username /
    Join tblUsers As U1
        On U1.u_username = D1.u_username
    Join tblUsers As U2
        On U2.u_username = D2.u_username
/
WHERE D1.U_userName < D1.f_username */

* Capture d'écran qui aide l'espérons expliquer tout cela.
http://www.marketing2go.co.il/SqlQuestion.jpg
Obtenir des champs qui existent mutuellement et non mutuellement dans la même table dans deux colonnes

Voici les résultats de la requête mise à jour (avec les 2 lignes commentées)
http://www.marketing2go.co.il/QueryResults.jpg
Les résultats requis doivent être sans lignes 1 et 2 (ou sans lignes 3 et 5), parce qu'ils sont en effet, une duplicité. C'est parce que cette paire existe dans les rangées 3 et 5 (l'ordre des noms dans chaque paire est sans importance). En l'absence d'un meilleur mot, c'est plutôt une duplicité logique.

Beaucoup Merci à l'avance

+0

Il peut être plus utile de montrer votre sortie préférée, les gens peuvent viser à obtenir les résultats que vous voulez. – Rick

Répondre

0

Ok, si je comprends bien, si les résultats comprennent déjà l'appariement (a, b), ils ne devraient pas inclure (b, a). Est-ce correct? Si c'est le cas, cela signifie que la cause première de votre problème est que la table tblDynamicUserList inclut à la fois les associations (a, b) et (b, a). Si nous filtrons d'abord ceux dans la requête, les résultats joints seront ce que vous attendiez. Notez que cela signifie également que vous ne vous souciez pas de savoir quel nom d'utilisateur est dans u_username et lequel est dans f_username; si cela importait, alors vous auriez besoin des deux dans les résultats.

Voici un script démontrant votre comportement actuel. Notez que la deuxième requête de votre question n'a pas produit les résultats que vous avez publiés. Je l'ai mis à jour à ce que je suppose que vous utilisez:

declare @tblUsers table (id int, u_username varchar(20), permission varchar(10), experience int, grade int) 
declare @tblDynamicUserList table (u_username varchar(20), f_username varchar(20), f_timestamp datetime default (getdate())) 

insert into @tblUsers values (1, 'RanAbraGmail', 'WiFi', 1, 2000) 
insert into @tblUsers values (2, 'Ana', 'Phone', 2, 3000) 
insert into @tblUsers values (3, 'RoyP', 'Phone', 5, 4000) 
insert into @tblUsers values (4, 'anaHeb', 'Phone', 14, 5000) 
insert into @tblUsers values (7, 'Sheleg', 'Phone', 15, 5500) 

insert into @tblDynamicUserList values ('ana', 'RanAbraGmail', default) 
insert into @tblDynamicUserList values ('anaHeb', 'RoyP', default) 
insert into @tblDynamicUserList values ('RanAbraGmail', 'Ana', default) 
insert into @tblDynamicUserList values ('RanAbraGmail', 'RoyP', default) 
insert into @tblDynamicUserList values ('RoyP', 'anaHeb', default) 
insert into @tblDynamicUserList values ('Sheleg', 'RanAbraGmail', default) 

Select D1.u_username, U1.Permission, U1.Grade, D1.f_username, U2.Permission, U2.Grade 
from @tblDynamicUserList As D1 
    Join @tblUsers As U1 
     On U1.u_username = D1.u_username 
    Join @tblUsers As U2 
     On U2.u_username = D1.f_username 

Par conséquent, cette requête produira les résultats que vous voulez, d'abord récupérer uniquement les appariements distincts de noms d'utilisateur, et seulement ensuite se joindre à la table des utilisateurs récupérer les détails.

Select D1.username1, U1.Permission, U1.Grade, D1.username2, U2.Permission, U2.Grade 
from (select distinct case when u_username < f_username then u_username else f_username end as username1, 
    case when u_username < f_username then f_username else u_username end as username2 
    from @tblDynamicUserList) As D1 
    Join @tblUsers As U1 
     On U1.u_username = D1.username1 
    Join @tblUsers As U2 
     On U2.u_username = D1.username2 
+0

Merci mais ce n'est pas une "Duplicité" normale qui peut être évitée en utilisant "Distinct". C'est plus comme une duplicité logique. Veuillez voir le bas de la question mise à jour avec la sortie actuelle et l'explication de la sortie préférée. – ranabra

+0

Rick merci beaucoup, travaillant comme requis :) Une dernière question rapide ... quelle serait l'efficacité de cette requête sur plusieurs milliers de paires de noms? – ranabra

+0

Ca devrait être plutôt bien. La sous-requête interne ne sera exécutée qu'une seule fois et réduira le nombre de lignes auxquelles SQL Server doit se joindre dans la requête externe. Je ne peux pas donner le timing de votre système bien sûr, mais à première vue, il ne serait que de 5 à 10% plus lent que votre requête originale. – Rick

Questions connexes