在分层查询中获取组Last / Max记录的可能方法?

时间:2010-12-20 17:09:06

标签: 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_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)

提前谢谢!

1 个答案:

答案 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