[英]get All Parents with no children or if there are children, get the latest child
我有下表的命令。 orderId
是主鍵, parentOrderId
是表示此訂單是否具有父訂單的列。
例如:1、2、3、4沒有父訂單。 5,6,7,8有上級訂單。
+--------------------+----------------------+
| order_id | parent_order_id |
+--------------------+----------------------+
| 1 | null|
| 2 | null|
| 3 | null|
| 4 | null|
| 5 | 1 |
| 6 | 2 |
| 7 | 3 |
| 8 | 3 |
+--------------------+----------------------+
I need to query all Parents with no children or if there are children only get the latest child.
The result I need is : 4,5,6,8
4 because it has no children and should be returned.
5 because it is the only child of 1.
6 because that is the only child of 2.
8 because 3 has 2 children(7,8) and I need to return latest child. Pick max of orderId's.
我試過了
SELECT
MAX(order_id)
FROM
orders
WHERE
parent_order_id IS NOT NULL
GROUP BY
parent_order_id
UNION ALL
SELECT
order_id
FROM
orders
WHERE
parent_order_id IS NULL
MINUS
SELECT
parent_order_id
FROM
orders;
我在尋找什么:
上面的查詢返回4,5,6,8。 問題是我正在將此查詢輸入IN子句,並且oracle對於IN子句有1000個限制。 我試圖看看是否有更好的方法使用聯接來解決此問題。 更新:聯接將幫助我檢索訂單表中的所有列,而不僅僅是id,為簡單起見,我僅包括兩列,表中還有更多列。 現在,我正在獲取id的第一個並將其輸入另一個查詢的子句中,以獲取與這些id匹配的所有列。
我也在尋找非特定於供應商的sql。
謝謝您的幫助。
這是解決此問題的一種方法,即使用connect by
查詢connect by
(實際上是一種connect by
形式-針對像您這樣的分層數據進行了優化)。 WITH子句不是解決方案的一部分,它僅用於模擬您的輸入。 使用實際的表名和列名。
請注意,我還會在結果中得到order_id = 5
的行(我在評論中問過這一點,您回答了其他問題,但沒有回答這個問題)。
這顯示了如何一次性獲得所需的所有列。
with
orders_table (order_id, parent_order_id) as (
select 1, null from dual union all
select 2, null from dual union all
select 3, null from dual union all
select 4, null from dual union all
select 5, 1 from dual union all
select 6, 2 from dual union all
select 7, 3 from dual union all
select 8, 3 from dual
)
select order_id, parent_order_id
from (
select o.*
, max(order_id)
over (partition by connect_by_root order_id) as max_id
from orders_table o
where connect_by_isleaf = 1
start with parent_order_id is null
connect by parent_order_id = prior order_id
)
where order_id = max_id
;
ORDER_ID PARENT_ORDER_ID
-------- ---------------
5 1
6 2
8 3
4
OP在對我的其他答案的評論中解釋說,他需要一個盡可能使用標准SQL功能的查詢。 這排除了connect by
查詢進行connect by
可能性,還排除了nvl()
這樣簡單的功能。
下面的查詢得到相同的結果。 它的通用性較低,但可以解決OP的問題(那里只有父母和孩子,而沒有“第三代”節點)。
就像我的其他答案一樣,它的編寫使得可以選擇原始表(或某些相關子集)中的所有列。 最好使用解析函數來完成,就像我在其他“答案”中所做的一樣。
with
orders_table (order_id, parent_order_id) as (
select 1, null from dual union all
select 2, null from dual union all
select 3, null from dual union all
select 4, null from dual union all
select 5, 1 from dual union all
select 6, 2 from dual union all
select 7, 3 from dual union all
select 8, 3 from dual
)
select order_id, parent_order_id
from (
select o.*
, max(order_id) over
(partition by coalesce(parent_order_id, order_id)) as max_id
from orders_table o
)
where order_id = max_id
;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.