[英]Oracle SQL - return multiple columns from subquery
讓我們在 Oracle 中進行一個簡單的查詢:
SELECT
CASE.ID,
CASE.TYPE,
CASE.DATE_RAISED
FROM
CASE
WHERE
CASE.DATE_RAISED > '2019-01-01'
現在假設另一個表 EVENT 包含多個事件,這些事件可能與每個案例相關聯(通過 EVENT.CASE_ID 鏈接)。 或根本不存在。 我想報告每個案例中最早日期的未來事件 - 或者如果不存在,則返回 NULL。 我可以使用 SELECT 子句中的子查詢來做到這一點,如下所示:
SELECT
CASE.ID,
CASE.TYPE,
CASE.DATE_RAISED,
(
SELECT
MIN(EVENT.DATE)
FROM
EVENT
WHERE
EVENT.CASE_ID = CASE.ID
AND EVENT.DATE >= CURRENT_DATE
) AS MIN_EVENT_DATE
FROM
CASE
WHERE
CASE.DATE_RAISED > '2019-01-01'
這將返回一個像這樣的表:
Case ID Case Type Date Raised Min Event Date
76 A 03/01/2019 10/05/2019
43 B 02/02/2019 [NULL]
89 A 29/01/2019 08/07/2019
90 A 04/03/2019 [NULL]
102 C 15/04/2019 20/05/2019
請注意,如果不存在任何符合條件的事件,則仍會返回該行但沒有值。 這是因為子查詢在 SELECT 子句中。 這工作得很好。
然而,我的問題是,如果我想從 EVENT 表中返回多於一列 - 同時仍然保留 EVENT 表中沒有匹配行的可能性。 上面的代碼只將 EVENT.DATE 作為單個子查詢結果返回到主查詢的一列。 但是如果我還想返回 EVENT.ID 或 EVENT.TYPE 呢? 雖然仍然允許它們為 NULL(如果沒有找到來自 CASE 的匹配記錄)?
我想我可以在 SELECT 子句中使用多個子查詢:每個子查詢只返回一列。 但這似乎非常低效,因為每個子查詢都基於相同的條件(CASE ID 與主查詢匹配的最小日期 EVENT;如果沒有發現此類事件,則為 NULL)。
我懷疑一些漂亮的連接將是答案 - 盡管我正在努力了解究竟是哪些。
請注意,上面的示例是我實際代碼的大大簡化版本,其中已經包含“舊式”Oracle 格式的多個連接,例如:
WHERE
CASE.ID(+) = EVENT.CASE_ID
這是有原因的 - 因此對任何回答這個問題的人提出要求,請您展示這種編碼風格的任何解決方案,因為我的 SQL 還不夠先進,無法重構“新”風格的連接到現有代碼中。
您可以使用join
和窗口函數。 例如:
select c.*, e.*
from c left join
(select e.*,
row_number() over (partition by e.case_id order by e.date desc) as seqnum
from events e
) e
on e.case_id = c.id and e.seqnum = 1;
where c.date_raised > date '2019-01-01'; -- assuming the value is a date
你是這個意思嗎? 我只是用舊的 Oracle 連接語法和你的代碼風格重寫了戈登的答案。
SELECT
CASE.ID,
CASE.TYPE,
CASE.DATE_RAISED,
MIN_E.DATE AS MIN_EVENT_DATE
FROM
CASE,
(SELECT EVENT.*,
ROW_NUMBER() OVER (PARTITION BY EVENT.CASE_ID ORDER BY EVENT.DATE DESC) AS SEQNUM
FROM
EVENT
WHERE
EVENT.DATE >= CURRENT_DATE
) MIN_E
WHERE
CASE.DATE_RAISED > DATE '2019-01-01'
AND MIN_E.CASE_ID (+) = CASE.ID
AND MIN_E.SEQNUM (+) = 1;
使用您想要的列創建對象類型並從子查詢中返回它。 您的查詢將類似於
SELECT
CASE.ID,
CASE.TYPE,
CASE.DATE_RAISED,
(
SELECT
t_your_new_type ( MIN(EVENT.DATE) , min ( EVENT.your_another_column ) )
FROM
EVENT
WHERE
EVENT.CASE_ID = CASE.ID
AND EVENT.DATE >= CURRENT_DATE
) AS MIN_EVENT_DATE
FROM
CASE
WHERE
CASE.DATE_RAISED > '2019-01-01'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.