1

我有一个具有以下外观的数据集。

A 1
A 2
A 3
B 1
B 2
B 3
B 4

这是使用以下命令的结果

select 
    connect_by_root id as root,
    level lvl

from
    dbset
start with id in ('A','B')
connect by nocycle child = prior parent)

我要结果

A 3
B 4

也就是说,我想提取每棵树的最高根。理想情况下,我希望在我拥有的相同命令中完成此操作,但我在该领域内太新手了,不知道如何去做。

4

5 回答 5

1

connect_by_isleaf 函数可能是您所追求的,例如:

WITH dbset AS (SELECT 'A' ID, 1 CHILD, NULL PARENT FROM dual UNION ALL
               SELECT 'A' ID, 2 CHILD, 1 PARENT FROM dual UNION ALL
               SELECT 'A' ID, 3 CHILD, 2 PARENT FROM dual UNION ALL
               SELECT 'B' ID, 1 CHILD, NULL PARENT FROM dual UNION ALL
               SELECT 'B' ID, 2 CHILD, 1 PARENT FROM dual UNION ALL
               SELECT 'B' ID, 3 CHILD, 2 PARENT FROM dual UNION ALL
               SELECT 'B' ID, 4 CHILD, 3 PARENT FROM dual)
SELECT connect_by_root ID AS root,
       LEVEL lvl,
       CONNECT_by_isleaf,
       CHILD, PARENT
FROM   dbset
WHERE  CONNECT_by_isleaf = 1
START WITH ID IN ('A', 'B') AND PARENT IS NULL
CONNECT BY NOCYCLE PRIOR CHILD = PARENT
           AND ID = PRIOR ID
ORDER BY root;

ROOT        LVL CONNECT_BY_ISLEAF      CHILD     PARENT
---- ---------- ----------------- ---------- ----------
A             3                 1          3          2
B             4                 1          4          3
于 2018-03-09T09:00:46.930 回答
1

这与 Tim Biegeleisen 的回答基本相同,只是完成了测试数据、结果、sql fiddle 和关于分区条件的更正。

注意:一旦蒂姆的答案得到纠正和完成,我很乐意删除这个答案。

测试数据:

create table dbset (id varchar(1), child varchar(1), parent varchar(1) );
insert into dbset values('A','A','A');
insert into dbset values('X','A','X');
insert into dbset values('Z','X','Z');
insert into dbset values('B','6','6');
insert into dbset values('G','6','7');
insert into dbset values('H','7','8');
insert into dbset values('I','8','9');

询问:

SELECT root, lvl
FROM
(
    SELECT 
        connect_by_root id AS root,
        level lvl,
        row_number() over (PARTITION BY connect_by_root id ORDER BY level DESC) rn
    FROM dbset
    START WITH id IN ('A','B')
    CONNECT BY NOCYCLE child = prior parent
) t
WHERE rn = 1;

结果:

| ROOT | LVL |
|------|-----|
|    A |   3 |
|    B |   4 |

Sql 小提琴:http ://sqlfiddle.com/#!4/37c70/8

于 2018-03-09T11:44:40.623 回答
1

只需使用group by

    create table t23 ( dt varchar(10) ,id1 int );
    insert all
      into t23 values('A',1)
      into t23 values('A',2)
      into t23 values('A',3)
      into t23 values('B',1)
      into t23 values('B',2)
      into t23 values('B',3)
      into t23 values('B',4)  
    select * from dual;
    select * from t23;
    select dt , max(id1)id1 from t23 group by dt;
于 2018-03-09T08:48:36.540 回答
1

使用ROW_NUMBER

SELECT root, lvl
FROM
(
    SELECT 
        connect_by_root id AS root,
        level lvl,
        row_number() over (PARTITION BY connect_by_root id ORDER BY level DESC) rn
    FROM dbset
    START WITH id IN ('A','B')
    CONNECT BY NOCYCLE child = prior parent
) t
WHERE rn = 1
于 2018-03-09T08:45:13.493 回答
0

使用排名函数row_number()获取每个根的最高记录。

select * from 
(
    select *,
         row_number() over (partition by id order by level desc) Seq 
    from table
) t
where Seq = 1
于 2018-03-09T08:43:49.467 回答