TSQL问题-链接表
我试图做一个非常直接的TSQL链接表,但我在第一个障碍时摔倒了,基本上我想要一个双向链接 例如 如果Contact 1添加Contact 2,则Contact 2连接到Contact 1(反之亦然),这意味着查询识别出他们是成对的 表格示例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
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'。嗨-请注意