3

我正在创建一个发送电子邮件的列表。登录的个人在数据库中有一个他们向谁报告的字段(除非有错误或他们没有向任何人报告)。

因此,例如,如果我登录并单击 SQL 中的提交按钮,它会说我向“John Doe”报告

然后,我需要获取“John Doe”向谁报告并将其添加到列表中。我需要继续爬升,直到我们到达公司的顶端(GID 将为空白或空)。

以我为例,我向'John Doe'谁汇报'Tom Doe'。汤姆向任何人报告他的usrReportsTo领域是这样的'00000000-0000-0000-0000-000000000000'

如果 usrReportsTo 字段是""NULL'00000000-0000-0000-0000-000000000000'则循环应该终止。

这是我使用的sql。

执行此循环的最干净/最简洁/最有效的方法是什么?在 SQL 或 ASP.net C# 中执行它更好吗?

select usrReportsTo from dbo.CVT_Users_usr, usrEmailAddress
WHERE RTRIM(usrFirstName) + ' ' + RTRIM(usrLastName) = 'James Wilson' 
-- Returns 'James Wilson' + email

SELECT RTRIM(usrFirstName) + ' ' + RTRIM(usrLastName) as Name, usrEmailAddress, usrReportsTo from dbo.CVT_Users_usr
WHERE usrGID = '38922F83-4B6E-499E-BF4F-EF0B094F47F7'
-- Returns 'John Doe' + email + reportsTo

SELECT RTRIM(usrFirstName) + ' ' + RTRIM(usrLastName) as Name, usrEmailAddress, usrReportsTo from dbo.CVT_Users_usr
WHERE usrGID = 'FB8F4939-3956-4834-9D89-D72AFB8BF3E0'
-- Returns 'Tom Doe' + email + reportsTo

编辑#3

SQL 的工作副本不会返回 100% 的真实数据。

使用 cte AS ( select usrGID, RTRIM(usrFirstName) + ' ' + RTRIM(usrLastName) as Name, usrEmailAddress, usrReportsTo from dbo.CVT_Users_usr union all select u.usrGID, RTRIM(u.usrFirstName) + ' ' + RTRIM(u. usrLastName), cte.usrEmailAddress, cte.usrReportsTo from dbo.CVT_Users_usr u inner join cte on u.usrReportsTo = cte.usrGID ) select * from cte where Name = 'James Wilson'

-- 退货

usrGID名称usrEmailAddress usrReportsTo E1DAFC11-BE35-4730-9961-68EEF8D85DE4詹姆斯·威尔逊38922F83-4B6E-499E-BF4F-EF0B094F47F7 E1DAFC11-BE35-4730-9961-68EEF8D85DE4詹姆斯·威尔逊john@1234.com FB8F4939-3956-4834-9D89,D72AFB8BF3E0 E1DAFC11 -BE35-4730-9961-68EEF8D85DE4 詹姆斯·威尔逊 tom@1234.com 00000000-0000-0000-0000-000000000000

usrGID 和名称不应该与 usrEmailAddress 和 usrReportsTo 匹配吗?我尝试将 sql 更改为 cte.USRGID 和 cte.Name 但它给出了最大递归错误。

有任何想法吗?

4

1 回答 1

6

使用 acommon table expression您可以在一条 SQL 语句中生成完整的结果集(通过递归连接),从而完全避免任何循环。

带有关键字段的基本示例

create table #CVT_Users_usr (usrGid uniqueidentifier, usrEmailAddress varchar(50), usrFirstName varchar(20), usrLastName varchar(20), usrReportsTo uniqueidentifier)

insert #CVT_Users_usr values    
('38922F83-4B6E-499E-BF4F-EF0B094F47F7' , 'james@wilson.com','james','wilson', 'E1DAFC11-BE35-4730-9961-68EEF8D85DE4'),
('E1DAFC11-BE35-4730-9961-68EEF8D85DE4', 'john@doe.com','john','doe', 'FB8F4939-3956-4834-9D89-D72AFB8BF3E0'),
('FB8F4939-3956-4834-9D89-D72AFB8BF3E0', 'tom@doe.com','tom','doe' ,'00000000-0000-0000-0000-000000000000'),
('FE6899A5-63BA-42B7-A70E-011711A5FAC6', 'ken@ken.com','ken', 'kenneths', 'FB8F4939-3956-4834-9D89-D72AFB8BF3E0')

declare @id uniqueidentifier
select @id = usrGid from #CVT_Users_usr where usrFirstName='james' and usrLastName='wilson'

;with cte as
(
select usrGid, usrEmailAddress, usrFirstName, usrLastName, usrReportsTo from #CVT_Users_usr
union all
select u.usrGid,  cte.usrEmailAddress, cte.usrFirstName, cte.usrLastName, cte.usrReportsTo 
from #CVT_Users_usr u
    inner join cte on u.usrReportsTo= cte.usrGid
)
    select usrFirstName + ' ' + usrLastName, usrEmailAddress  from cte
    where usrGid=@id

drop table #CVT_Users_usr
于 2012-08-20T21:33:10.153 回答