假设我有一张像这样的表:
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')
所以我需要的是为每个用户找到 last (这意味着活动)委派。
我已经找到了一个解决方案,我决定不在这里展示(除非每个人都忽略了我,这总是有可能)。我只能说这是一个有点长的答案,而且肯定好像用大炮来杀死跳蚤......
但是你会怎么做?考虑任何可用的相关SQL Server扩展,并注意我们正在寻找既优雅又具有良好性能的答案......
BTW,这是预期的结果集:
id user_from user_to
----------- ---------- ----------
1 ANTHONY JOHN
2 JOHN JOHN
3 KARL HANS
4 JOSHUA HANS
5 PIOTR HANS
(5 row(s) affected)
提前谢谢!
答案 0 :(得分:1)
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