繁体   English   中英

Oracle SQL:从多个表中提取数据

[英]Oracle SQL: Extracting data from multiple tables

我有 3 个表,比如 TabA、TabB 和 TabC。 以下是这些表中一些有用的列:

TabA(ID VARCHAR2 Primary Key, ..)

TabB(ID VARCHAR2, Value CHAR(1), LastUpdated Date)

TabC(ID VARCHAR2 Primary Key, Value CHAR(1), LastUpdated Date)

这里的Value是一个标志“Y”或“N”。 我想使用这 3 个表获取所有ID和它们的Value 首先,我想查看所有表中存在的所有不同ID 由于Value不在 TabA 中,我将仅在 TabB 和 TabC 中查找Value 如果对于特定的IDValue不在任何表中,我将假定它为“N”。 假设对于特定ID ,该值同时在 TabB 和 TabC 中,我想取LastUpdated更大的Value

我尝试过使用循环,但这不是非常有效的解决方案。 我只需要结果游标中的KeyValue ,并希望为此保留一个查询。

有人可以帮助确定比使用循环更好的解决方案。

编辑 -

这是一个示例:

假设 TabA 是 -

ID
100
101
102

TabB 是 -

ID 价值 最近更新时间
99 22 年 5 月 21 日
100 ñ 22-5-22
103 ñ 22 年 5 月 23 日

TabC 是 -

ID 价值 最近更新时间
102 22 年 5 月 20 日
103 22 年 5 月 24 日
104 ñ 22 年 5 月 21 日

结果应该是——

ID 价值 为什么?
99 来自 TabB
100 ñ 来自 TabB
101 ñ 仅在 TabA 中默认 N
102 来自 TabC
103 在 TabB 和 TabC 中,但 LastUpdated 在 TabC 中更大,因此取 TabC 值
104 ñ 来自 TabC

编辑 -

如果 ID 在 TabB 和 TabC 中具有相同的 LastUpdated 但值不同,则预期结果 - 这可以忽略,因为这种情况很少见。 我们可以假设这永远不会发生。

你可以尝试这样的事情:

SELECT id, value FROM
(SELECT id, value, ROW_NUMBER()
OVER (PARTITION BY id ORDER BY lastupdated DESC) AS rownr
FROM
(SELECT id, 'N' AS value, sysdate AS lastupdated FROM taba
WHERE id NOT IN (SELECT id FROM tabb) 
AND id NOT IN (SELECT id FROM tabc)
UNION
SELECT id, value, MAX(lastupdated) AS lastupdated
FROM tabb
GROUP BY id, value
UNION
SELECT id, value, MAX(lastupdated) AS lastupdated
FROM tabc
GROUP BY id, value
ORDER BY id, lastupdated DESC)) WHERE rownr = 1;

至少在我的小提琴示例中,这可以正常工作: db<>fiddle

如果IDTabBTabCLastUpdated相同但Value不同,请定义预期结果。 在跟随它是未定义的。

WITH BC AS (
    SELECT ID, VALUE FROM (
        SELECT ID, VALUE, 
        ROW_NUMBER() OVER (PARTITION BY ID ORDER BY LastUpdated DESC) r
        FROM (
            SELECT ID, Value, MAX(LastUpdated) AS LastUpdated
            FROM TabB
            GROUP BY ID, Value
            UNION ALL
            SELECT ID, Value, MAX(LastUpdated) AS LastUpdated
            FROM TabC
            GROUP BY ID, Value
        )
    )
    WHERE R = 1
)
SELECT ID, VALUE FROM BC
UNION ALL
SELECT ID, 'N' VALUE FROM tabA A
WHERE A.ID NOT IN (
    SELECT ID FROM BC
)
ORDER BY ID;

使用UNION从多个表创建单个数据集。 然后,过滤该数据集。

SELECT ID, Value
FROM
(
    SELECT ID, Value, MAX(LastUpdated) AS LastUpdated
    FROM TabB
    GROUP BY ID, Value
    UNION ALL
    SELECT ID, Value, MAX(LastUpdated) AS LastUpdated
    FROM TabC
    GROUP BY ID, Value
) t
WHERE ID IN
(
    SELECT DISTINCT ID
    FROM TabA
)
AND
(
    Value = 'Y' OR
    NOT EXISTS
    (
        SELECT 1
        FROM
        (
            SELECT ID, Value
            FROM
            (
                SELECT ID, Value, MAX(LastUpdated) AS LastUpdated
                FROM TabB
                GROUP BY ID, Value
                UNION ALL
                SELECT ID, Value, MAX(LastUpdated) AS LastUpdated
                FROM TabC
                GROUP BY ID, Value
            ) t
            WHERE ID = t.ID
        )
    )
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM