在分层查询中获取组最后/最大记录的可能方法?

发布于 2024-10-08 04:26:02 字数 1499 浏览 3 评论 0原文

假设我有一个像这样的表:

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)

提前致谢!

Assuming I have a table like this one:

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)
)

So an user A has to right to delegate her system access to another user B. When she does that, she won't be able to access the system anymore - user B will have to "break" that delegation before she is able to use the system again...

BUT also consider that, if user B delegates access to user C, user C will also start impersonating user A, and so on.

(I know this seems to be a security nightmare - please let's just forget about that, OK? :-))

Also consider those records:

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')

So what I need is finding the last (which means the active) delegation for each user.

I have come to a solution that I've decided to not show here (unless everybody ignores me, which is always a possibility). All I can say is that it is a somewhat long answer, and it surely seems like using a cannon to kill a flea...

But how would you do that? Consider any relevant SQL Server extension available, and notice we're looking for an answer that is both elegant and with a good performance...

BTW, this is the expected result set:

id          user_from  user_to   
----------- ---------- ----------
1           ANTHONY    JOHN      
2           JOHN       JOHN      
3           KARL       HANS      
4           JOSHUA     HANS      
5           PIOTR      HANS      

(5 row(s) affected)

And thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

裸钻 2024-10-15 04:26:02
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
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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文