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

时间:2019-03-15 16:19:41

标签: sql oracle

我的情况是我有一个与链中先前记录相关的记录“链”。链的长度(记录数)可以是一个记录,也可以是两个或更多记录。

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

我已经编写了几个SELECTS来实现相同的结果,但是我不确定如何从此处轻松地将其升级到具有数十条记录的链,无论它是如何对SELECT或LOOP进行选择。以其他方式代替手动写入每个SELECT,直到没有更多记录返回为止。我正在寻找循环,但是我对如何完成自己想要的事情还不太清楚。

<a href="#contact">Contact us</a>
...
<section id="contact">

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

SELECT ID,COLB,COLC,SOURCE FROM TABLE WHERE SOURCE IN
  (SELECT ID FROM TABLE WHERE SOURCE IN
     (SELECT ID FROM TABLE WHERE ID='ABC123')
  );
---------------------
SELECT T3.ID,T3.COLB,T3.COLC,T3.SOURCE
FROM TABLE T1
JOIN TABLE T2 ON T1.ID=T2.SOURCE
JOIN TABLE T3 ON T2.ID=T3.SOURCE
WHERE T1.ID='ABC123';

如果我想查询WHERE COLB = 1,我知道我可以从SOURCE IS NULL CONNECT BY PRIOR ID = SOURCE开始。这是一种解决方法,但是,它包括具有该COLB值的所有记录,并且我无法使用WHERE ID ='[value]'进行查询,因为它仅返回一个等于ID的记录。我想使用ID进行查询,并让它仅返回其链中的相关记录。

能帮助我走上正确的道路的任何帮助-感谢。

1 个答案:

答案 0 :(得分:1)

递归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');