Oracle 11g 分层查询需要继承一些数据
Oracle 11g hierarchical query needs some inherited data
表格看起来有点像:
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_id
的 meat_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
我可以 post 一些失败的尝试来修改我上面的查询,但它们是相当令人尴尬的失败。在超出基础知识之前,我根本没有使用过分层查询,所以我希望有一些我不知道应该搜索的关键字或概念。
我 post 在底部自己编辑了一个答案以显示我最终得到的结果。我将接受另一个答案,因为他们能够使数据对我来说更清晰,没有它,我将一事无成。
你内心的疑问是正确的。当 flag 为 Y 时,您只需要从内部查询的 meat_id 列中选择最右边的数字。
我已经使用 REGEXP_SUBSTR 函数来获取最右边的数字和 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 |
查询 2:
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
table 相比较。大写字母可以稍微优化一下,但我已经完成了查询的这一部分,所以....它现在必须保留。
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
(你有没有想过,当你读到这样的问题时,真正的模式是什么?显然我不是在做炸玉米饼项目。或者只要保留一般关系和概念,它甚至重要吗? )
表格看起来有点像:
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_id
的 meat_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
我可以 post 一些失败的尝试来修改我上面的查询,但它们是相当令人尴尬的失败。在超出基础知识之前,我根本没有使用过分层查询,所以我希望有一些我不知道应该搜索的关键字或概念。
我 post 在底部自己编辑了一个答案以显示我最终得到的结果。我将接受另一个答案,因为他们能够使数据对我来说更清晰,没有它,我将一事无成。
你内心的疑问是正确的。当 flag 为 Y 时,您只需要从内部查询的 meat_id 列中选择最右边的数字。 我已经使用 REGEXP_SUBSTR 函数来获取最右边的数字和 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 |
查询 2:
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
table 相比较。大写字母可以稍微优化一下,但我已经完成了查询的这一部分,所以....它现在必须保留。
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
(你有没有想过,当你读到这样的问题时,真正的模式是什么?显然我不是在做炸玉米饼项目。或者只要保留一般关系和概念,它甚至重要吗? )