如何呈现 id 树/分层查询
How to present tree of id / hierarchical query
一直在和分层查询作斗争,最后不得不放弃。
我需要提供所有 tree/hierarchy 输入的 ID。
也许最好的方法是在示例中展示我想做的事情:
CREATE TABLE ORDERS (ID NUMBER)
;
CREATE TABLE PRODUCTS (ID NUMBER,ORDER_ID NUMBER, PARENT_ID NUMBER)
;
CREATE TABLE WANT_TO_PRESENT (ID NUMBER);
INSERT INTO ORDERS VALUES (65733);
INSERT INTO ORDERS VALUES (23423);
INSERT INTO ORDERS VALUES (456765);
INSERT INTO ORDERS VALUES (23464);
INSERT INTO ORDERS VALUES (77532);
INSERT INTO PRODUCTS VALUES (1,65733,3);
INSERT INTO PRODUCTS VALUES (2,23423,3);
INSERT INTO PRODUCTS VALUES (3,77532,4);
INSERT INTO PRODUCTS VALUES (4,23464,0);
INSERT INTO PRODUCTS VALUES (5,456765,null);
示例 1:
INSERT INTO WANT_TO_PRESENT(ID) VALUES (23464)
那么输出应该只有 23464 因为 parent_id = 0
或 null
示例 2:
INSERT INTO WANT_TO_PRESENT(ID) VALUES (23423)
那么输出应该是:65733,23423,77532,23464
为什么是 65733 - 因为 parent_id 和 23423 一样。
示例 3:
INSERT INTO WANT_TO_PRESENT(ID) VALUES (23464,65733)
那么输出应该是:输出应该是:
65733,23423,77532,23464, 65733 - 同上
我想知道我是否真的需要 table 订单来展示树,尽管我在产品 table 中找到的所有数据。
你能给我一些提示吗?一些解释,我想终于明白分层查询是如何工作的...
编辑:
insert into products values (6,23422,7);
insert into products values (7,56435,0);
truncate table WANT_TO_PRESENT;
INSERT INTO WANT_TO_PRESENT(ID) VALUES (56435);
您必须合并两个查询:
首先爬到 PRODUCT
table 中 parent 的 ID 的根目录。然后从这个根向下到所有的孩子。
有一件事让它变得更加困难。产品 4 的根 parent 0,但没有包含此键的记录。产品 5 是根并且具有 parent NULL。这是在 START WITH
子句中处理的,如果您使用唯一表示法,可以简化该子句。
with to_root as (
select
t1.id,
connect_by_root(t1.PARENT_ID) as root
from
products t1
where t1.id in (select id from PRODUCTS
where ORDER_ID in (select id from WANT_TO_PRESENT))
start with nvl(t1.PARENT_ID,0) = 0
connect by t1.PARENT_ID = prior t1.id
),
go_down as (
select
t1.id,
t1.parent_id
from
products t1
start with PARENT_ID in (select root from to_root) or
ID in (select ID from to_root)
connect by t1.PARENT_ID = prior t1.id
)
--select * from to_root;
select ORDER_ID from PRODUCTS
where id in (
select id from go_down
)
order by 1
;
给你测试数据:
truncate table WANT_TO_PRESENT;
INSERT INTO WANT_TO_PRESENT(ID) VALUES (23464);
23423
23464
65733
77532
truncate table WANT_TO_PRESENT;
INSERT INTO WANT_TO_PRESENT(ID) VALUES (456765);
456765
truncate table WANT_TO_PRESENT;
INSERT INTO WANT_TO_PRESENT(ID) VALUES (23464);
INSERT INTO WANT_TO_PRESENT(ID) VALUES (65733);
23423
23464
65733
77532
Oracle 11g R2 架构设置:
CREATE TABLE ORDERS (ID NUMBER PRIMARY KEY);
INSERT INTO ORDERS VALUES (65733);
INSERT INTO ORDERS VALUES (23423);
INSERT INTO ORDERS VALUES (456765);
INSERT INTO ORDERS VALUES (23464);
INSERT INTO ORDERS VALUES (77532);
insert into ORDERS values (23422);
insert into ORDERS values (56435);
CREATE TABLE PRODUCTS (
ID NUMBER PRIMARY KEY,
ORDER_ID NUMBER REFERENCES ORDERS(ID),
PARENT_ID NUMBER
);
INSERT INTO PRODUCTS VALUES (1,65733,3);
INSERT INTO PRODUCTS VALUES (2,23423,3);
INSERT INTO PRODUCTS VALUES (3,77532,4);
INSERT INTO PRODUCTS VALUES (4,23464,0);
INSERT INTO PRODUCTS VALUES (5,456765,null);
insert into products values (6,23422,7);
insert into products values (7,56435,0);
查询 1:
WITH WantToPresent( ID ) AS (
SELECT 23464 FROM DUAL
)
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY ID = PRIOR parent_id
UNION
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY PRIOR ID = parent_id
UNION
SELECT p2.ORDER_ID
FROM PRODUCTS p1
INNER JOIN
PRODUCTS p2
ON ( p1.PARENT_ID = p2.PARENT_ID AND p2.PARENT_ID <> 0 )
INNER JOIN
WantToPresent w
ON ( p1.ORDER_ID = w.ID )
| ORDER_ID |
|----------|
| 23423 |
| 23464 |
| 65733 |
| 77532 |
查询 2:
WITH WantToPresent( ID ) AS (
SELECT 23423 FROM DUAL
)
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY
ID = PRIOR parent_id
UNION
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY PRIOR ID = parent_id
UNION
SELECT p2.ORDER_ID
FROM PRODUCTS p1
INNER JOIN
PRODUCTS p2
ON ( p1.PARENT_ID = p2.PARENT_ID AND p2.PARENT_ID <> 0 )
INNER JOIN
WantToPresent w
ON ( p1.ORDER_ID = w.ID )
| ORDER_ID |
|----------|
| 23423 |
| 23464 |
| 65733 |
| 77532 |
查询 3:
WITH WantToPresent( ID ) AS (
SELECT 23464 FROM DUAL UNION ALL
SELECT 65733 FROM DUAL
)
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY
ID = PRIOR parent_id
UNION
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY PRIOR ID = parent_id
UNION
SELECT p2.ORDER_ID
FROM PRODUCTS p1
INNER JOIN
PRODUCTS p2
ON ( p1.PARENT_ID = p2.PARENT_ID AND p2.PARENT_ID <> 0 )
INNER JOIN
WantToPresent w
ON ( p1.ORDER_ID = w.ID )
| ORDER_ID |
|----------|
| 23423 |
| 23464 |
| 65733 |
| 77532 |
查询 4:
WITH WantToPresent( ID ) AS (
SELECT 56435 FROM DUAL
)
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY
ID = PRIOR parent_id
UNION
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY PRIOR ID = parent_id
UNION
SELECT p2.ORDER_ID
FROM PRODUCTS p1
INNER JOIN
PRODUCTS p2
ON ( p1.PARENT_ID = p2.PARENT_ID AND p2.PARENT_ID <> 0 )
INNER JOIN
WantToPresent w
ON ( p1.ORDER_ID = w.ID )
| ORDER_ID |
|----------|
| 23422 |
| 56435 |
一直在和分层查询作斗争,最后不得不放弃。
我需要提供所有 tree/hierarchy 输入的 ID。
也许最好的方法是在示例中展示我想做的事情:
CREATE TABLE ORDERS (ID NUMBER)
;
CREATE TABLE PRODUCTS (ID NUMBER,ORDER_ID NUMBER, PARENT_ID NUMBER)
;
CREATE TABLE WANT_TO_PRESENT (ID NUMBER);
INSERT INTO ORDERS VALUES (65733);
INSERT INTO ORDERS VALUES (23423);
INSERT INTO ORDERS VALUES (456765);
INSERT INTO ORDERS VALUES (23464);
INSERT INTO ORDERS VALUES (77532);
INSERT INTO PRODUCTS VALUES (1,65733,3);
INSERT INTO PRODUCTS VALUES (2,23423,3);
INSERT INTO PRODUCTS VALUES (3,77532,4);
INSERT INTO PRODUCTS VALUES (4,23464,0);
INSERT INTO PRODUCTS VALUES (5,456765,null);
示例 1:
INSERT INTO WANT_TO_PRESENT(ID) VALUES (23464)
那么输出应该只有 23464 因为 parent_id = 0
或 null
示例 2:
INSERT INTO WANT_TO_PRESENT(ID) VALUES (23423)
那么输出应该是:65733,23423,77532,23464
为什么是 65733 - 因为 parent_id 和 23423 一样。
示例 3:
INSERT INTO WANT_TO_PRESENT(ID) VALUES (23464,65733)
那么输出应该是:输出应该是:
65733,23423,77532,23464, 65733 - 同上
我想知道我是否真的需要 table 订单来展示树,尽管我在产品 table 中找到的所有数据。
你能给我一些提示吗?一些解释,我想终于明白分层查询是如何工作的...
编辑:
insert into products values (6,23422,7);
insert into products values (7,56435,0);
truncate table WANT_TO_PRESENT;
INSERT INTO WANT_TO_PRESENT(ID) VALUES (56435);
您必须合并两个查询:
首先爬到 PRODUCT
table 中 parent 的 ID 的根目录。然后从这个根向下到所有的孩子。
有一件事让它变得更加困难。产品 4 的根 parent 0,但没有包含此键的记录。产品 5 是根并且具有 parent NULL。这是在 START WITH
子句中处理的,如果您使用唯一表示法,可以简化该子句。
with to_root as (
select
t1.id,
connect_by_root(t1.PARENT_ID) as root
from
products t1
where t1.id in (select id from PRODUCTS
where ORDER_ID in (select id from WANT_TO_PRESENT))
start with nvl(t1.PARENT_ID,0) = 0
connect by t1.PARENT_ID = prior t1.id
),
go_down as (
select
t1.id,
t1.parent_id
from
products t1
start with PARENT_ID in (select root from to_root) or
ID in (select ID from to_root)
connect by t1.PARENT_ID = prior t1.id
)
--select * from to_root;
select ORDER_ID from PRODUCTS
where id in (
select id from go_down
)
order by 1
;
给你测试数据:
truncate table WANT_TO_PRESENT;
INSERT INTO WANT_TO_PRESENT(ID) VALUES (23464);
23423
23464
65733
77532
truncate table WANT_TO_PRESENT;
INSERT INTO WANT_TO_PRESENT(ID) VALUES (456765);
456765
truncate table WANT_TO_PRESENT;
INSERT INTO WANT_TO_PRESENT(ID) VALUES (23464);
INSERT INTO WANT_TO_PRESENT(ID) VALUES (65733);
23423
23464
65733
77532
Oracle 11g R2 架构设置:
CREATE TABLE ORDERS (ID NUMBER PRIMARY KEY);
INSERT INTO ORDERS VALUES (65733);
INSERT INTO ORDERS VALUES (23423);
INSERT INTO ORDERS VALUES (456765);
INSERT INTO ORDERS VALUES (23464);
INSERT INTO ORDERS VALUES (77532);
insert into ORDERS values (23422);
insert into ORDERS values (56435);
CREATE TABLE PRODUCTS (
ID NUMBER PRIMARY KEY,
ORDER_ID NUMBER REFERENCES ORDERS(ID),
PARENT_ID NUMBER
);
INSERT INTO PRODUCTS VALUES (1,65733,3);
INSERT INTO PRODUCTS VALUES (2,23423,3);
INSERT INTO PRODUCTS VALUES (3,77532,4);
INSERT INTO PRODUCTS VALUES (4,23464,0);
INSERT INTO PRODUCTS VALUES (5,456765,null);
insert into products values (6,23422,7);
insert into products values (7,56435,0);
查询 1:
WITH WantToPresent( ID ) AS (
SELECT 23464 FROM DUAL
)
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY ID = PRIOR parent_id
UNION
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY PRIOR ID = parent_id
UNION
SELECT p2.ORDER_ID
FROM PRODUCTS p1
INNER JOIN
PRODUCTS p2
ON ( p1.PARENT_ID = p2.PARENT_ID AND p2.PARENT_ID <> 0 )
INNER JOIN
WantToPresent w
ON ( p1.ORDER_ID = w.ID )
| ORDER_ID |
|----------|
| 23423 |
| 23464 |
| 65733 |
| 77532 |
查询 2:
WITH WantToPresent( ID ) AS (
SELECT 23423 FROM DUAL
)
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY
ID = PRIOR parent_id
UNION
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY PRIOR ID = parent_id
UNION
SELECT p2.ORDER_ID
FROM PRODUCTS p1
INNER JOIN
PRODUCTS p2
ON ( p1.PARENT_ID = p2.PARENT_ID AND p2.PARENT_ID <> 0 )
INNER JOIN
WantToPresent w
ON ( p1.ORDER_ID = w.ID )
| ORDER_ID |
|----------|
| 23423 |
| 23464 |
| 65733 |
| 77532 |
查询 3:
WITH WantToPresent( ID ) AS (
SELECT 23464 FROM DUAL UNION ALL
SELECT 65733 FROM DUAL
)
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY
ID = PRIOR parent_id
UNION
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY PRIOR ID = parent_id
UNION
SELECT p2.ORDER_ID
FROM PRODUCTS p1
INNER JOIN
PRODUCTS p2
ON ( p1.PARENT_ID = p2.PARENT_ID AND p2.PARENT_ID <> 0 )
INNER JOIN
WantToPresent w
ON ( p1.ORDER_ID = w.ID )
| ORDER_ID |
|----------|
| 23423 |
| 23464 |
| 65733 |
| 77532 |
查询 4:
WITH WantToPresent( ID ) AS (
SELECT 56435 FROM DUAL
)
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY
ID = PRIOR parent_id
UNION
SELECT ORDER_ID
FROM PRODUCTS p
START WITH
EXISTS( SELECT 'X'
FROM WantToPresent w
WHERE p.ORDER_ID = w.ID )
CONNECT BY PRIOR ID = parent_id
UNION
SELECT p2.ORDER_ID
FROM PRODUCTS p1
INNER JOIN
PRODUCTS p2
ON ( p1.PARENT_ID = p2.PARENT_ID AND p2.PARENT_ID <> 0 )
INNER JOIN
WantToPresent w
ON ( p1.ORDER_ID = w.ID )
| ORDER_ID |
|----------|
| 23422 |
| 56435 |