【问题标题】:Get the immediate parent child relation in a table获取表中的直接父子关系
【发布时间】:2020-09-15 21:24:31
【问题描述】:

我有一个具有以下值的表

userid   roleid   ranklvl
123         a       1
456         b       2
789         c       3

我需要以上格式的输出数据:

userid   roleid   ranklvl  parentroleid
123         a       1        null
456         b       2        a
789         c       3        b

在此先感谢您提供任何指导。

编辑: 我使用了 while 循环方法来实现这一点,但试图避免 while 循环。

declare @a table
(
userid int,roleid char(1),ranklvl int,parentroleid char(1) )

insert into @a(userid,roleid,ranklvl) select userid,roleid,ranklvl from Table [where some condition]

declare @maxcount smallint  = (select max(ranklvl) from @a)
declare @counter smallint = 1
declare @parentroleid char(1)

while( @maxcount >  @counter)
BEGIN
    Select @parentroleid  = roleid from @a where ranklvl  = @maxcount - 1
    UPDATE @a SET parentrole = @parentroleid where ranklvl  = @maxcount
    SET @maxcount = @maxcount -1
END

select * from @a

如果ranklvl 的正确序列对于给定的记录集(如 1->2->3)存在,则 while 循环逻辑起作用。但如果数据采用以下方式,它就不起作用:

userid   roleid   ranklvl
123         a       1
789         c       3

以下预期结果不是由 while 循环逻辑得出的。

userid   roleid   ranklvl  parentroleid
123         a       1       null
789         c       3       a

【问题讨论】:

  • 请向我们展示您的尝试。
  • 看看JOIN

标签: sql sql-server left-join sql-server-2017


【解决方案1】:

我想你想要一个自我加入:

select t.*, p.roleid parentroleid
from mytable t
left join mytable p on p.ranklvl = t.ranklvl - 1

如果排序列有空格,可以先枚举:

with cte as (
    select t.*, row_number() over(order by ranklvl) rn
    from mytable t
)
select c.*, p.roleid parentroleid
from cte c
left join cte p on p.rn = c.rn - 1

【讨论】:

  • 感谢您的逻辑。我最初使用 while 循环来实现这一点,但正如我在编辑部分中提到的,如果存在正确的序列 3->2->1 它可以工作,但是如果像这样的序列 3->1 则循环逻辑不起作用
  • 再次感谢。我今天学到了一个新的逻辑。要补充的一件事。在您的最后一个查询中,在自连接部分 mytable 将被 cte 替换。
  • @ArunJoy:确实...已修复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-25
  • 1970-01-01
  • 1970-01-01
  • 2017-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多