Oracle 11g分层查询需要一些继承的数据

Oracle 11g分层查询需要一些继承的数据,oracle,hierarchy,Oracle,Hierarchy,表看起来有点像: create table taco ( taco_id int primary key not null, taco_name varchar(255), taco_prntid int, meat_id int, meat_inht char(1) -- inherit meat ) 数据如下所示: insert into taco values (1, '1', null,

表看起来有点像:

create table taco (
    taco_id     int primary key not null, 
    taco_name   varchar(255), 
    taco_prntid int, 
    meat_id     int,
    meat_inht   char(1)  -- inherit meat
)        
数据如下所示:

insert into taco values (1, '1',      null,     1,  'N'); 
insert into taco values (2, '1.1',       1,  null,  'Y');
insert into taco values (3, '1.1.1',     2,  null,  'N');
insert into taco values (4, '1.2',       1,     2,  'N');
insert into taco values (5, '1.2.1',     4,  null,  'Y');
insert into taco values (6, '1.1.2',     2,  null,  'Y');
或者

- 1     has a meat_id=1 
- 1.1   has a meat_id=1 because it inherits from its parent via taco_prntid=1
- 1.1.1 has a meat_id of null because it does NOT inherit from its parent 
- 1.2   has a meat_id=2 and it does not inherit from its parent
- 1.2.1 has a meat_id=2 because it does inherit from its parent via taco_prntid=4
- 1.1.2 has a meat_id=1 because it does inherit from its parent via taco_prntid=2

现在。。。我究竟该如何查询每个
taco\u id
meat\u id
是什么?在我意识到我没有使用继承标志并且我的一些数据被弄乱之前,下面的内容一直有效

select  x.taco_id,  
        x.taco_name, 
        to_number(substr(meat_id,instr(rtrim(meat_id), ' ', -1)+1)) as meat_id 

from    (   select   taco_id, 
                     taco_name,  
                     level-1 "level", 
                     sys_connect_by_path(meat_id, ' ') meat_id
            from     taco
            start    with taco_prntid is null 
            connect  by prior taco_id = taco_prntid 
        ) x        
我可以发布一些失败的尝试来修改上面的查询,但它们都是相当令人尴尬的失败。除了基础知识之外,我还没有使用过分层查询,所以我希望有一些我不知道应该搜索的关键字或概念



我自己在底部贴了一个答案,以显示我最终得到了什么。我将另一个答案保留为已接受,因为他们能够让我更清楚地了解数据,如果没有它,我将一事无成。

您的内部查询是正确的。当flag为Y时,只需从内部查询的meat_id列中选择最右边的数字。 我使用了REGEXP_SUBSTR函数来获取最右边的number和CASE语句来检查标志

查询1

select  taco_id,  
        taco_name,
        taco_prntid,
        case meat_inht
            when 'N' then meat_id
            when 'Y' then to_number(regexp_substr(meat_id2,'\d+\s*$'))
        end meat_id,
        meat_inht
from    (   select   taco_id, 
                     taco_name,
                     taco_prntid,
                     meat_id,
                     meat_inht,
                     level-1 "level", 
                     sys_connect_by_path(meat_id, ' ') meat_id2
            from     taco
            start    with taco_prntid is null 
            connect  by prior taco_id = taco_prntid 
        )
order by 1
| TACO_ID | TACO_NAME | TACO_PRNTID | MEAT_ID | MEAT_INHT |
|---------|-----------|-------------|---------|-----------|
|       1 |         1 |      (null) |       1 |         N |
|       2 |       1.1 |           1 |       1 |         Y |
|       3 |     1.1.1 |           2 |  (null) |         N |
|       4 |       1.2 |           1 |       2 |         N |
|       5 |     1.2.1 |           4 |       2 |         Y |
|       6 |     1.1.2 |           2 |       1 |         Y |
select   taco_id, 
                     taco_name,
                     taco_prntid,
                     meat_id,
                     meat_inht,
                     level-1 "level", 
                     sys_connect_by_path(meat_id, ' ') meat_id2
            from     taco
            start    with taco_prntid is null 
            connect  by prior taco_id = taco_prntid 
| TACO_ID | TACO_NAME | TACO_PRNTID | MEAT_ID | MEAT_INHT | LEVEL | MEAT_ID2 |
|---------|-----------|-------------|---------|-----------|-------|----------|
|       1 |         1 |      (null) |       1 |         N |     0 |     1    |
|       2 |       1.1 |           1 |  (null) |         Y |     1 |     1    |
|       3 |     1.1.1 |           2 |  (null) |         N |     2 |     1    |
|       6 |     1.1.2 |           2 |  (null) |         Y |     2 |     1    |
|       4 |       1.2 |           1 |       2 |         N |     1 |     1 2  |
|       5 |     1.2.1 |           4 |  (null) |         Y |     2 |     1 2  |

select  taco_id,  
        taco_name,
        taco_prntid,
        case meat_inht
            when 'N' then meat_id
            when 'Y' then to_number(regexp_substr(meat_id2,'\d+\s*$'))
        end meat_id,
        meat_inht
from    (   select   taco_id, 
                     taco_name,
                     taco_prntid,
                     meat_id,
                     meat_inht,
                     level-1 "level", 
                     sys_connect_by_path(meat_id, ' ') meat_id2
            from     taco
            start    with taco_prntid is null 
            connect  by prior taco_id = taco_prntid 
        )
order by 1
| TACO_ID | TACO_NAME | TACO_PRNTID | MEAT_ID | MEAT_INHT |
|---------|-----------|-------------|---------|-----------|
|       1 |         1 |      (null) |       1 |         N |
|       2 |       1.1 |           1 |       1 |         Y |
|       3 |     1.1.1 |           2 |  (null) |         N |
|       4 |       1.2 |           1 |       2 |         N |
|       5 |     1.2.1 |           4 |       2 |         Y |
|       6 |     1.1.2 |           2 |       1 |         Y |
select   taco_id, 
                     taco_name,
                     taco_prntid,
                     meat_id,
                     meat_inht,
                     level-1 "level", 
                     sys_connect_by_path(meat_id, ' ') meat_id2
            from     taco
            start    with taco_prntid is null 
            connect  by prior taco_id = taco_prntid 
| TACO_ID | TACO_NAME | TACO_PRNTID | MEAT_ID | MEAT_INHT | LEVEL | MEAT_ID2 |
|---------|-----------|-------------|---------|-----------|-------|----------|
|       1 |         1 |      (null) |       1 |         N |     0 |     1    |
|       2 |       1.1 |           1 |  (null) |         Y |     1 |     1    |
|       3 |     1.1.1 |           2 |  (null) |         N |     2 |     1    |
|       6 |     1.1.2 |           2 |  (null) |         Y |     2 |     1    |
|       4 |       1.2 |           1 |       2 |         N |     1 |     1 2  |
|       5 |     1.2.1 |           4 |  (null) |         Y |     2 |     1 2  |
查询2

select  taco_id,  
        taco_name,
        taco_prntid,
        case meat_inht
            when 'N' then meat_id
            when 'Y' then to_number(regexp_substr(meat_id2,'\d+\s*$'))
        end meat_id,
        meat_inht
from    (   select   taco_id, 
                     taco_name,
                     taco_prntid,
                     meat_id,
                     meat_inht,
                     level-1 "level", 
                     sys_connect_by_path(meat_id, ' ') meat_id2
            from     taco
            start    with taco_prntid is null 
            connect  by prior taco_id = taco_prntid 
        )
order by 1
| TACO_ID | TACO_NAME | TACO_PRNTID | MEAT_ID | MEAT_INHT |
|---------|-----------|-------------|---------|-----------|
|       1 |         1 |      (null) |       1 |         N |
|       2 |       1.1 |           1 |       1 |         Y |
|       3 |     1.1.1 |           2 |  (null) |         N |
|       4 |       1.2 |           1 |       2 |         N |
|       5 |     1.2.1 |           4 |       2 |         Y |
|       6 |     1.1.2 |           2 |       1 |         Y |
select   taco_id, 
                     taco_name,
                     taco_prntid,
                     meat_id,
                     meat_inht,
                     level-1 "level", 
                     sys_connect_by_path(meat_id, ' ') meat_id2
            from     taco
            start    with taco_prntid is null 
            connect  by prior taco_id = taco_prntid 
| TACO_ID | TACO_NAME | TACO_PRNTID | MEAT_ID | MEAT_INHT | LEVEL | MEAT_ID2 |
|---------|-----------|-------------|---------|-----------|-------|----------|
|       1 |         1 |      (null) |       1 |         N |     0 |     1    |
|       2 |       1.1 |           1 |  (null) |         Y |     1 |     1    |
|       3 |     1.1.1 |           2 |  (null) |         N |     2 |     1    |
|       6 |     1.1.2 |           2 |  (null) |         Y |     2 |     1    |
|       4 |       1.2 |           1 |       2 |         N |     1 |     1 2  |
|       5 |     1.2.1 |           4 |  (null) |         Y |     2 |     1 2  |

select  taco_id,  
        taco_name,
        taco_prntid,
        case meat_inht
            when 'N' then meat_id
            when 'Y' then to_number(regexp_substr(meat_id2,'\d+\s*$'))
        end meat_id,
        meat_inht
from    (   select   taco_id, 
                     taco_name,
                     taco_prntid,
                     meat_id,
                     meat_inht,
                     level-1 "level", 
                     sys_connect_by_path(meat_id, ' ') meat_id2
            from     taco
            start    with taco_prntid is null 
            connect  by prior taco_id = taco_prntid 
        )
order by 1
| TACO_ID | TACO_NAME | TACO_PRNTID | MEAT_ID | MEAT_INHT |
|---------|-----------|-------------|---------|-----------|
|       1 |         1 |      (null) |       1 |         N |
|       2 |       1.1 |           1 |       1 |         Y |
|       3 |     1.1.1 |           2 |  (null) |         N |
|       4 |       1.2 |           1 |       2 |         N |
|       5 |     1.2.1 |           4 |       2 |         Y |
|       6 |     1.1.2 |           2 |       1 |         Y |
select   taco_id, 
                     taco_name,
                     taco_prntid,
                     meat_id,
                     meat_inht,
                     level-1 "level", 
                     sys_connect_by_path(meat_id, ' ') meat_id2
            from     taco
            start    with taco_prntid is null 
            connect  by prior taco_id = taco_prntid 
| TACO_ID | TACO_NAME | TACO_PRNTID | MEAT_ID | MEAT_INHT | LEVEL | MEAT_ID2 |
|---------|-----------|-------------|---------|-----------|-------|----------|
|       1 |         1 |      (null) |       1 |         N |     0 |     1    |
|       2 |       1.1 |           1 |  (null) |         Y |     1 |     1    |
|       3 |     1.1.1 |           2 |  (null) |         N |     2 |     1    |
|       6 |     1.1.2 |           2 |  (null) |         Y |     2 |     1    |
|       4 |       1.2 |           1 |       2 |         N |     1 |     1 2  |
|       5 |     1.2.1 |           4 |  (null) |         Y |     2 |     1 2  |

这就是我到目前为止的结局。。。在接受的答案中应用逻辑后。我又添加了一些内容,以便将结果与我的
meat
表结合起来。大写字母可以优化一点,但我对查询的这一部分非常熟悉,所以。。。。它必须暂时停留

select  x.taco_id,  
        x.taco_name, 
        x.taco_prntname,
        meat_id  

        ,case when to_number(regexp_substr(meat_id,'\d+\s*$'))=0 then null else
            to_number(regexp_substr(meat_id,'\d+\s*$')) end as meat_id 

from    (   select   taco_id, 
                     taco_name,  
                     taco_prntname,
                     level-1 "level", 

                     sys_connect_by_path( 
                        case when meat_inht='N' then nvl(to_char(meat_id),'0') else '' end   
                     ,' ') meat_id 

            from     taco join jobdtl on jobdtl.jobdtl_id=taco.jobdtl_id 
            start    with taco_prntid is null 
            connect  by prior taco_id = taco_prntid 
        ) x  

(当你读到这样的问题时,你有没有想过,真正的模式是什么?很明显,我不是在做一个玉米卷项目。或者,只要保留了一般的关系和概念,这就很重要了?

这对你有帮助吗?我们错过了一个案子。但我认为看到这一点后,可能很容易处理。某个对象可能具有meat_id=1,然后子对象继承,下一个子对象不继承,但具有空值,然后下一个子对象继承空值。我需要一种方法来提取空值。所以我要做的就是。。。。是改变我所连接的。。。并使用。。。空间为空。。。而且。。。之后把它清理干净。