如何呈现 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 = 0null

示例 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

SQL Fiddle

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 )

Results:

| 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 )

Results:

| 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 )

Results:

| 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 )

Results:

| ORDER_ID |
|----------|
|    23422 |
|    56435 |