我正在尝试在Oracle中编写一个选择查询,其中结果按组“隔离”。每个组都有一个带有一些子级的父级实体,因此我想对行进行分组,使每个组均以父级实体开头,后跟相应的子级。
表具有以下结构:
ID | CREATION_DATE | MASTER_ID
33 | 2019-07-01 09:31:04 | null
52 | 2019-07-01 10:45:04 | null
64 | 2019-07-01 11:00:04 | 33
71 | 2019-07-01 11:01:04 | 52
72 | 2019-07-01 12:31:04 | 33
到目前为止,我尝试了以下代码,这些代码返回未按MASTER_ID分组但在CREATION_DATE正确排序的行:
SELECT ID, CREATION_DATE, MASTER_ID
FROM ENTITY
WHERE CREATION_DATE >= TO_DATE('06-01-2019','MM-DD-YYYY')
ORDER BY CREATION_DATE DESC
我想找到一种返回以下结构的方法:
ID | CREATION_DATE | MASTER_ID
33 | 2019-07-01 09:31:04 | null
64 | 2019-07-01 11:00:04 | 33
72 | 2019-07-01 12:31:04 | 33
52 | 2019-07-01 10:45:04 | null
71 | 2019-07-01 11:01:04 | 52
问题在于父实体一直都是null
,所以我不能使用GROUP BY
。
您对我应该如何处理有任何建议吗?
答案 0 :(得分:0)
您可以通过使用connect by
分层查询以及order siblings by
子句来完成此操作,例如:
WITH your_table AS (SELECT 33 ID, to_date('2019-07-01 09:31:04', 'yyyy-mm-dd hh24:mi:ss') creation_date, NULL master_id FROM dual UNION ALL
SELECT 52 ID, to_date('2019-07-01 10:45:04', 'yyyy-mm-dd hh24:mi:ss') creation_date, NULL master_id FROM dual UNION ALL
SELECT 72 ID, to_date('2019-07-01 12:31:04', 'yyyy-mm-dd hh24:mi:ss') creation_date, 33 master_id FROM dual UNION ALL
SELECT 64 ID, to_date('2019-07-01 11:00:04', 'yyyy-mm-dd hh24:mi:ss') creation_date, 33 master_id FROM dual UNION ALL
SELECT 71 ID, to_date('2019-07-01 11:01:04', 'yyyy-mm-dd hh24:mi:ss') creation_date, 52 master_id FROM dual)
SELECT ID,
creation_date,
master_id,
connect_by_root(ID) top_id
FROM your_table
START WITH master_id IS NULL
CONNECT BY PRIOR ID = master_id
ORDER SIBLINGS BY creation_date;
ID CREATION_DATE MASTER_ID TOP_ID
---------- ------------- ---------- ----------
33 01/07/2019 09 33
64 01/07/2019 11 33 33
72 01/07/2019 12 33 33
52 01/07/2019 10 52
71 01/07/2019 11 52 52
答案 1 :(得分:0)
我认为使用动态列进行排序很简单。
WITH your_table AS (SELECT 33 ID, to_date('2019-07-01 09:31:04', 'yyyy-mm-dd hh24:mi:ss') creation_date, NULL master_id FROM dual UNION ALL
SELECT 52 ID, to_date('2019-07-01 10:45:04', 'yyyy-mm-dd hh24:mi:ss') creation_date, NULL master_id FROM dual UNION ALL
SELECT 72 ID, to_date('2019-07-01 12:31:04', 'yyyy-mm-dd hh24:mi:ss') creation_date, 33 master_id FROM dual UNION ALL
SELECT 64 ID, to_date('2019-07-01 11:00:04', 'yyyy-mm-dd hh24:mi:ss') creation_date, 33 master_id FROM dual UNION ALL
SELECT 71 ID, to_date('2019-07-01 11:01:04', 'yyyy-mm-dd hh24:mi:ss') creation_date, 52 master_id FROM dual)
SELECT
ID,
CREATION_DATE,
MASTER_ID
FROM
(
SELECT
ID,
CREATION_DATE,
MASTER_ID,
CASE
WHEN MASTER_ID IS NULL THEN 0
ELSE 1
END AS RN
FROM
YOUR_TABLE
ORDER BY
CASE
WHEN MASTER_ID IS NULL THEN ID
ELSE MASTER_ID
END,
RN
);
干杯!
答案 2 :(得分:0)
如果您只有一个层次结构,则只需执行以下操作:
select t.*
from t
order by coalesce(t.master_id, t.id),
t.creation_date