TSQL问题-链接表

TSQL问题-链接表,sql,sql-server,tsql,Sql,Sql Server,Tsql,我试图做一个非常直接的TSQL链接表,但我在第一个障碍时摔倒了,基本上我想要一个双向链接 例如 如果Contact 1添加Contact 2,则Contact 2连接到Contact 1(反之亦然),这意味着查询识别出他们是成对的 表格示例 RelatedDataID UniqueID Related_UniqueID ------------------------------------------- 1 AA BB 2

我试图做一个非常直接的TSQL链接表,但我在第一个障碍时摔倒了,基本上我想要一个双向链接

例如

如果Contact 1添加Contact 2,则Contact 2连接到Contact 1(反之亦然),这意味着查询识别出他们是成对的

表格示例

RelatedDataID  UniqueID   Related_UniqueID  
-------------------------------------------    
1              AA          BB   
2              CC          DD                     
3
用户表

UserID  UniqueID   Username
----------------
1        AA       Bob    
2        BB       Fred    
3        CC       Charlie
4        DD       Billy
因此,基本上,当我使用UniqueID“AA”运行查询时,它将返回

Username     RelatedID
------------------------    
Bob          1    
Fred         1    
Charlie      0
Billy        0
但当我在UniqueID“CC”上运行它时,它也应该返回

Username   RelatedID
---------------------
Bob        0    
Fred       0    
Charlie    2
Billy      2
有人知道我怎样才能做到这一点吗?我当前的存储过程似乎只返回已链接的存储过程,而不返回未链接的存储过程。我需要它返回所有用户的完整列表,但要让RelatedID返回为0或RelatedDataID

UniqueID是guid

这里是我的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))
只需将UniqueID(filter/where)条件移动到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
只需将UniqueID(filter/where)条件移动到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
UPDATE)鉴于您在评论中提到UniqueId列是guid,并且您希望在没有关系时返回零,我们必须将guid的大小写为varchar。如果给定用户具有多个关系,那么预期输出应该是什么也不清楚。此查询将选择User.UniqueID=RelatedData.UniqueID上的关系,而不是User.UniqueID=RelatedData.Related\u UniqueID上的关系,但每个用户只返回一行

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
UPDATE)鉴于您在评论中提到UniqueId列是guid,并且您希望在没有关系时返回零,我们必须将guid的大小写为varchar。如果给定用户具有多个关系,那么预期输出应该是什么也不清楚。此查询将选择User.UniqueID=RelatedData.UniqueID上的关系,而不是User.UniqueID=RelatedData.Related\u UniqueID上的关系,但每个用户只返回一行

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


在这里不重要,因为
''=''或null=1
的计算结果为
true或unknown
,其计算结果为true@Andomar-您是否考虑过它在何处连接到RelatedData,因此ISNULL会发出嘶嘶声,并且所有可用的连接记录都不适合@UniqueID?这就是为什么WHERE过滤器会删除记录只是一个旁注:它应该显示所有记录,但RelatedDataID应该显示两个ID之间是否存在任何关系。你说得对,我只是在看连接没有成功的情况。这里不重要,因为
''=''或null=1
的计算结果为
true或unknown
,其计算结果为true@Andomar-您是否考虑过它在何处连接到RelatedData,因此ISNULL会发出嘶嘶声,并且所有可用的连接记录都不适合@UniqueID?这就是为什么WHERE过滤器会删除记录只是一个旁注:它应该显示所有记录,但RelatedDataID应该显示两个ID之间是否存在任何关系。你是对的,我只看了连接没有成功的情况。如果可能,请提供更详细的示例;当UniqueID=2没有行时,为什么Bob有UniqueID=2的关系?如果Bob有多个关系会发生什么?例如,假设他是弗雷德和查理的亲戚,我想做的是建立一个双向链接。例如,如果我传递UniqueID“1”,并且UniqueID 1链接到UniqueID 2,它将显示所有联系人,但标记UniqueID 1链接到UniqueID 2,反之亦然。因此,如果我放置UniqueID 2,它将获得所有联系人,并显示UniqueID 1是链接的(因此是RelatedDataID),我根据WHERE-vs-JOIN条件的预感进行了尝试。但我承认,即使是你最新的编辑,我仍然无法理解输出。在uniq=1中,为什么bob show 1和charlie show 2??您正走在EAV的危险道路上,这条道路夺走了许多年轻开发人员的生命。在进一步尝试之前,请阅读这里:如果可能,请提供更详细的示例;当UniqueID=2没有行时,为什么Bob有UniqueID=2的关系?如果Bob有多个关系会发生什么?例如,假设他是弗雷德和查理的亲戚,我想做的是建立一个双向链接。例如,如果我传递UniqueID“1”,并且UniqueID 1链接到UniqueID 2,它将显示所有联系人,但标记UniqueID 1链接到UniqueID 2,反之亦然。因此,如果我放置UniqueID 2,它将获得所有联系人,并显示UniqueID 1是链接的(因此是RelatedDataID),我根据WHERE-vs-JOIN条件的预感进行了尝试。但我承认,即使是你最新的编辑,我仍然无法理解输出。在uniq=1中,为什么bob show 1和charlie show 2??您正走在EAV的危险道路上,这条道路夺走了许多年轻开发人员的生命。在进一步冒险之前,请阅读这里:嗨-请注意UniqueID是一个varchar(36)(GUID)。但这段代码似乎不起作用。例如,如果在相关的_数据中,UniqueID“D”和UniqueID“E”之间存在链接,当我传入“D”和“E”时,应该显示它们彼此链接。@Tech-UniqueID是guid,这是应该在OP中的关键信息。类似地,边缘事例数据应与其相应的样本输出一起包含在样本数据中。@Tech-我已更新了我的响应,以说明UniqueId列是guid这一事实。然而,你能用你提到的边缘案例更新你的文章吗。请记住,您的查询是根据一个特定的@UniqueId关系进行过滤的,因此请在您的示例输出中用这个新数据说明这一点。@Tech-我已经更新了我的解决方案。但是,如果给定用户除了('AA','BB')之外还有多个关系(例如('AA','CC')?如果存在主关系和次关系(例如('AA','BB')和('DD','AA'),会发生什么情况?嗨,Thomas,这只是两个记录之间的双向关系。即,如果在SP中输入'AA',它将返回'AA','BB'关系以及'DD','AA'。嗨-请注意