2011-01-19 3 views
2

J'essaie de faire une table de liaison TSQL assez droite mais je tombe à la première haie, fondamentalement je veux un lien bidirectionnel.TSQL Problème - Table de lien

Par exemple ....

En cas de contact 1 ajoute contact 2, contactez 2 est connecté à contacter 1 (et vice versa) l'idée étant que la requête reconnaît qu'ils sont jumelés.

Tableau Exemple

RelatedDataID UniqueID Related_UniqueID 
-------------------------------------------  
1    AA   BB 
2    CC   DD      
3 

utilisateurs Tableau

UserID UniqueID Username 
---------------- 
1  AA  Bob  
2  BB  Fred  
3  CC  Charlie 
4  DD  Billy 

Donc, fondamentalement, quand je lance une requête avec UniqueID "AA" il retournera

Username  RelatedID 
------------------------  
Bob   1  
Fred   1  
Charlie  0 
Billy  0 

Mais aussi quand je le lance sur UniqueID "CC" il devrait retourner

Username RelatedID 
--------------------- 
Bob  0  
Fred  0  
Charlie 2 
Billy  2 

Est-ce que quelqu'un sait comment je peux y parvenir? Ma procédure stockée actuelle semble seulement ramener ceux qui sont liés, et non ceux qui ne sont pas liés. J'en ai besoin pour ramener une liste complète de tous les utilisateurs, mais pour que l'identificateur RelatedID revienne sous la forme d'un 0 ou de l'identificateur RelatedDataID.

Les ID uniques sont des GUID.

Voici mon instruction TSQL.

ALTER PROCEDURE sp_Test 
@CompanyID int, 
@UniqueID varchar(36), 
@PersonTypeID int 
AS 
BEGIN 
SET NOCOUNT ON; 

SELECT 
    First_Name + ' ' + Last_Name AS Full_Name, 
    ISNULL(RelatedDataID,0) AS RelatedDataID 
FROM 
    Users 
LEFT JOIN 
    Related_Data 
ON 
    Users.UniqueID = Related_Data.UniqueID 
WHERE 
    Users.PersonTypeID = @PersonTypeID 
AND 
    Users.Deleted = '0' 
AND 
    ((ISNULL(Related_Data.UniqueID,'') = '') OR (Related_Data.UniqueID = @UniqueID OR Related_Data.Related_UniqueID = @UniqueID)) 
+0

Si possible, fournir un exemple plus détaillé; pourquoi Bob a-t-il une relation pour UniqueID = 2, lorsqu'il n'y a pas de lignes pour UniqueID = 2? – Andomar

+0

Que se passe-t-il si Bob a plusieurs relations? Par exemple, supposons qu'il soit lié à Fred et Charlie. – Thomas

+0

Ce que j'essaie de faire est d'avoir un lien bidirectionnel. Un exemple serait si j'ai passé UniqueID "1" et UniqueID 1 a été lié à UniqueID 2, il montrerait tous les contacts, mais signaler que UniqueID 1 a été lié à UniqueID 2 et vice versa. Donc, si je mets UniqueID 2, il obtiendrait tous les contacts, et montrerait que UniqueID 1 était lié (d'où RelatedDataID) – Tech

Répondre

0

(MISE À JOUR) Étant donné que vous avez mentionné dans les commentaires que les colonnes uniqueID sont guids et que vous voulez un zéro pour retourner quand aucune relation, nous devons caser les guids à varchar. Il n'est pas clair non plus ce que la sortie attendue devrait être si un utilisateur donné a plusieurs relations. Cette requête choisira une relation sur User.UniqueID = RelatedData.UniqueId sur une relation sur User.UniqueId = RelatedData.Related_UniqueId mais ne retournera qu'une ligne par utilisateur.

Select U.username 
    , U.FirstName + ' ' + U.LastName As Full_Name 
, Case 
    When RD.Related_UniqueID Is Not Null Then RD.RelatedDataId 
    When RD1.UniqueId Is Not Null Then RD1.RelatedDataId 
    Else 0 
    End As RelatedID 
From Users As U 
    Left Join Related_Data As RD 
     On RD.UniqueID = U.UniqueId 
      And (
       RD.Related_UniqueID = @UniqueId 
       Or RD.UniqueId = @UniqueId 
       ) 
    Left Join Related_Data As RD1 
     On RD1.Related_UniqueID = U.UniqueId 
      And RD1.UniqueID = @UniqueId 
Where U.Deleted = '0' 
    And U.PersonTypeId = @PersonTypeId 
+0

Salut - veuillez noter que UniqueID est un varchar (36) (un GUID). Ce code ne semble pas fonctionner cependant. Un exemple serait, si dans Related_Data, il y avait un lien entre UniqueID 'D' et UniqueID 'E', quand j'ai passé en 'D' et 'E' il devrait montrer qu'ils sont liés les uns aux autres. – Tech

+0

@Tech - Que UniqueId est un guid est une information critique qui devrait être dans le PO. De même, les données de cas marginales doivent être incluses dans vos données d'échantillon avec leur sortie d'échantillon appropriée. – Thomas

+0

Yup - Mettra à jour le texte principal désolé! – Tech

0

Il suffit de déplacer le UniqueID (filtre/où) la condition dans la condition du LEFT JOIN

ALTER PROCEDURE sp_Test 
@CompanyID int, 
@UniqueID varchar(36), 
@PersonTypeID int 
AS 
BEGIN 
SET NOCOUNT ON; 

SELECT 
    First_Name + ' ' + Last_Name AS Full_Name, 
    ISNULL(RelatedDataID,0) AS RelatedDataID 
FROM 
    Users 
LEFT JOIN 
    Related_Data 
ON 
    Users.UniqueID = Related_Data.UniqueID 
AND 
    ((ISNULL(Related_Data.UniqueID,'') = '') OR (Related_Data.UniqueID = @UniqueID OR Related_Data.Related_UniqueID = @UniqueID)) 
WHERE 
    Users.PersonTypeID = @PersonTypeID 
AND 
    Users.Deleted = '0' 
END 
+0

N'importe pas ici, puisque ''' = '' OR null = 1' évalue à' vrai ou inconnu' qui évalue à vrai – Andomar

+0

@Andomar - avez-vous considéré où il parvient à se joindre à RelatedData, de sorte que le ISNULL pétille, ET tous les enregistrements joints disponibles ne correspondent pas à @UniqueID? C'est pourquoi les enregistrements sont supprimés par le filtre WHERE – RichardTheKiwi

+0

Juste une note de côté: il doit afficher TOUS les enregistrements, mais l'ID de données liées doit indiquer s'il existe une relation entre les deux ID. – Tech