簡體   English   中英

Oracle SQL - 從子查詢返回多列

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM