【问题标题】:SQL query to get list of all records that are placed higher in hierarchySQL查询以获取在层次结构中较高的所有记录的列表
【发布时间】:2020-05-06 15:14:36
【问题描述】:

表格:

+-----+------------+-------------+
| Id  | DocumentNo | ParentCCID  |
+-----+------------+-------------+
|  10 | CC001      | NULL        |
|  20 | CC002      | CC001       |
|  33 | CC003      | CC002       |
+-----+-------------+-------------+

传递给查询的值:CC003

预期输出:

CC003
CC002
CC001

尝试失败:

select b2.documentno,b2.ParentCCID  from basicdetails  b1 
inner join basicdetails b2 on b1.documentno = b2.ParentCCID 
where b2.documentno='CC003' 

注意:DocumentNo 是唯一的主键。如果没有父记录,ParentCCID 可能有空值。

编辑:

create table basicdetails2
  (
    id int identity,
    documentno varchar(30),
    parentccid varchar(30)
  )
    insert into basicdetails2 values('CC001', null)
    insert into basicdetails2 values('CC002', 'CC001')
    insert into basicdetails2 values('CC003', 'CC002')
    insert into basicdetails2 values('CC004', 'CC003')

【问题讨论】:

  • 为什么尝试失败?

标签: sql sql-server database tsql


【解决方案1】:

你想要一个递归 cte:

with cte as (
      select bd.documentno, bd.ParentCCID
      from basicdetails bd
      where bd.documentno = 'CC003'
      union all
      select cte.documentno, cte.ParentCCID
      from cte join
           basicdetails bd
           on bd.documentno = cte.ParentCCID
     )
select bd.documentno
from cte;

【讨论】:

  • @SamuraiJack 我认为join 应该是on bd.documentno = cte.ParentCCID。第二个select 应该是bd.documentno, bd.ParentCCID,而不是cte.
【解决方案2】:

对 Gordon 的回答稍作改动(已经 +1)。

我喜欢跟踪关卡并查看每条记录的父母

示例

Declare @Fetch varchar(25) = 'CC003'

;with cte as (
      Select DocumentNo
            ,ParentCCDocumentNo
            ,Lvl=1
      From   YourTable 
      Where  DocumentNo=@Fetch
      Union  All
      Select R.DocumentNo
            ,R.ParentCCDocumentNo
            ,P.Lvl+1
      From   YourTable R
      Join   cte P on P.ParentCCDocumentNo = R.DocumentNo)
Select Lvl = Row_Number() over (Order By Lvl Desc)
      ,DocumentNo
      ,ParentCCDocumentNo
From cte
Order By 1 desc

退货

Lvl DocumentNo  ParentCCDocumentNo
3   CC003       CC002
2   CC002       CC001
1   CC001       NULL

【讨论】:

  • 这样可行,但我想知道是否有非递归的解决方案?
  • @SamuraiJack 从技术上讲是的,但它们可能会有点难看,特别是如果你有一个可变深度层次结构..你是否一次寻找多个路径?
  • 深度可以变化,但记录只有一个直接父项
  • @SamuraiJack 因为你有一个变量或锯齿状的层次结构,那么递归 CTE 是迄今为止最好的选择。只是您考虑的另一种选择stackoverflow.com/questions/49695115/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多