Sql 如何根据相关记录的值选择记录,直到为空

Sql 如何根据相关记录的值选择记录,直到为空,sql,oracle,Sql,Oracle,我的场景是,我有一个与链中的前一个记录相关的记录链。链的长度记录数可以是一条记录或两条或多条记录 在下面的示例中,有三条记录。链中的原始记录将具有已知的ID值和空源。下一条记录的源值将是前一条记录的ID。第三条记录的源等于第二条记录的ID。此趋势将持续,直到没有与源相关的ID为止 我已经编写了几个选择,它们实现了相同的结果,但我不确定从这里到哪里可以轻松地将其升级到一个可能包含数十条记录的链,无论是如何循环选择还是其他方式,而不是手动编写每个选择,直到没有更多记录返回。我正在研究循环,但我不太清

我的场景是,我有一个与链中的前一个记录相关的记录链。链的长度记录数可以是一条记录或两条或多条记录

在下面的示例中,有三条记录。链中的原始记录将具有已知的ID值和空源。下一条记录的源值将是前一条记录的ID。第三条记录的源等于第二条记录的ID。此趋势将持续,直到没有与源相关的ID为止

我已经编写了几个选择,它们实现了相同的结果,但我不确定从这里到哪里可以轻松地将其升级到一个可能包含数十条记录的链,无论是如何循环选择还是其他方式,而不是手动编写每个选择,直到没有更多记录返回。我正在研究循环,但我不太清楚如何实现我想要的

TABLE
   ID  |  COLB  |  COLC  |  SOURCE
-------------------------------------------------
ABC100 |   1    |   0    |  NULL
ABC101 |   1    |   1    |  ABC100
ABC102 |   1    |   1    |  ABC101
ABC152 |   1    |   1    |  NULL
ABC173 |   1    |   3    |  ABC152
ABC300 |   1    |   2    |  NULL
ABC301 |   1    |   3    |  ABC300
我知道如果我想查询COLB=1的位置,我可以从SOURCE IS NULL CONNECT BY PRIOR ID=SOURCE开始。这是一个解决方法,但是,它包括所有具有该COLB值的记录,我不能使用WHERE ID='[value]'进行查询,因为它只返回一个与ID相等的记录。我希望使用ID进行查询,并让它只返回其链中的相关记录


任何有助于我走上正确道路的帮助,我都很感激。

递归CTE可以:

with 
x (id, colb, colc, initial_id, next_source, generation) as (
  select id, colb, colc, source, id, 1 from my_table where id = 'ABC102'
  union all
  select x.id, x.colb, x.colc, t.id, t.source as next_source, x.generation + 1
  from x
  join my_table t on t.id = x.next_source
)
select id, colb, colc, initial_id
from x
where generation = (select max(generation) from x)
结果:

ID      COLB  COLC  INITIAL_ID
------  ----  ----  ----------
ABC102  1     0     ABC100    
作为参考,我使用了以下数据:

create table my_table (
  id varchar2(10),
  colb int,
  colc int,
  source varchar2(10)
);

insert into my_table (id, colb, colc, source) values ('ABC100', 1, 0, null);
insert into my_table (id, colb, colc, source) values ('ABC101', 1, 0, 'ABC100');
insert into my_table (id, colb, colc, source) values ('ABC102', 1, 0, 'ABC101');

嘿,非常感谢你。这管用!最大生成数与CONNECT BY和查询所有与COLB相关的生成数的级别一致。我喜欢这一代还表明在最后一代之前还有多少记录。再次感谢!
ID      COLB  COLC  INITIAL_ID
------  ----  ----  ----------
ABC102  1     0     ABC100    
create table my_table (
  id varchar2(10),
  colb int,
  colc int,
  source varchar2(10)
);

insert into my_table (id, colb, colc, source) values ('ABC100', 1, 0, null);
insert into my_table (id, colb, colc, source) values ('ABC101', 1, 0, 'ABC100');
insert into my_table (id, colb, colc, source) values ('ABC102', 1, 0, 'ABC101');