Sql 在分层查询中获取组Last/Max记录的可能方法?
假设我有一张这样的桌子:Sql 在分层查询中获取组Last/Max记录的可能方法?,sql,sql-server-2008,recursion,hierarchical-data,Sql,Sql Server 2008,Recursion,Hierarchical Data,假设我有一张这样的桌子: CREATE TABLE user_delegates ( [id] INT IDENTITY(1,1) NOT NULL, [user_from] VARCHAR(10) NOT NULL, [user_to] VARCHAR(10) NOT NULL, CONSTRAINT [PK_user_delegates] PRIMARY KEY CLUSTERED ([id] ASC), CONSTRAINT [UK_user_del
CREATE TABLE user_delegates (
[id] INT IDENTITY(1,1) NOT NULL,
[user_from] VARCHAR(10) NOT NULL,
[user_to] VARCHAR(10) NOT NULL,
CONSTRAINT [PK_user_delegates] PRIMARY KEY CLUSTERED ([id] ASC),
CONSTRAINT [UK_user_delegates] UNIQUE ([user_from] ASC)
)
因此,用户A有权将其系统访问权委托给另一个用户B。当她这样做时,她将无法再访问该系统-用户B必须“中断”该委托,然后才能再次使用该系统
也可以考虑,如果用户B授权访问用户C,用户C也将开始冒充用户A,等等。 (我知道这似乎是一场安全噩梦——请让我们忘掉它,好吗?:-))
也考虑那些记录:
INSERT INTO user_delegates([user_from], [user_to]) values ('ANTHONY', 'JOHN')
INSERT INTO user_delegates([user_from], [user_to]) values ('JOHN', 'JOHN')
INSERT INTO user_delegates([user_from], [user_to]) values ('KARL', 'JOSHUA')
INSERT INTO user_delegates([user_from], [user_to]) values ('JOSHUA', 'PIOTR')
INSERT INTO user_delegates([user_from], [user_to]) values ('PIOTR', 'HANS')
因此,我需要的是为每个用户查找最后一个(这意味着活动的)委派
我找到了一个解决方案,我决定不在这里展示(除非每个人都忽略我,这总是一种可能性)。我所能说的是,这是一个有点长的答案,它肯定像是用大炮杀死跳蚤
但是你会怎么做呢?考虑任何可用的SQL Server扩展名,注意我们正在寻找一个既美观又性能好的答案…
顺便说一句,这是预期的结果集:
id user_from user_to
----------- ---------- ----------
1 ANTHONY JOHN
2 JOHN JOHN
3 KARL HANS
4 JOSHUA HANS
5 PIOTR HANS
(5 row(s) affected)
提前谢谢你 很好。。。但是你错过了像
WHERE ud.user_from!=ud.user_to
在UNION ALL
之后的查询中(否则,DB引擎将抛出“最大递归已用尽”错误)。但我想有一条像“约翰代表约翰”这样的规则是邪恶的。。。即使这正是这个问题所基于的实际应用程序所发生的情况:P@rsenna:如果存在循环,查询自然会超过递归限制并失败。您的意思是忽略错误?好的,我会考虑…谢谢@rsenna:不是忽略,而是将其视为循环(或委托太深)的标志。
WITH q (user_initial, user_from, user_to, link) AS
(
SELECT user_id, user_id, user_id, link
FROM users
UNION ALL
SELECT user_initial, q.user_to, ud.user_to, link + 1
FROM q
JOIN user_delegates ud
ON ud.user_from = q.user_to
)
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY user_initial ORDER BY link DESC) rn
FROM q
)
WHERE rn = 1