验证两个表之间的信息 - Oracle SQL

时间:2018-01-05 11:45:17

标签: sql oracle

我需要2个表来验证某些信息,例如:

表A(GTM_LICENSE_LINE):

License Nº - License Line Nº
123 - 123_1
123 - 123_2

表B(GTM_LICENSE_LINE_ITEM):

License Line Nº - Item Nº
123_1 - XXX

但是,我需要验证是否存在没有关联项目的许可证行(所有行必须只有一个项目)。

如果条件为真(所有许可证行都有关联项),我的预期结果将为“1”,如果条件为假,则为null。我正在尝试使用LEFT JOIN和GROUP BY,但它对我不起作用。

SELECT u.GTM_LICENSE_LINE_GID 
FROM GTM_LICENSE_LINE I 
LEFT JOIN GTM_LICENSE_LINE_ITEM U 
    ON I.LICENSE_LINE_GID = U.GTM_LICENSE_LINE_GID 
WHERE i.LICENSE_GID = 'ELEB.L001' 
  AND U.GTM_LICENSE_LINE_GID is null 
GROUP BY U.GTM_LICENSE_LINE_GID 
HAVING COUNT(*) > 0 

如何使用Oracle SQL执行此操作?有什么建议吗?

由于

1 个答案:

答案 0 :(得分:0)

我想你可能会这样:

WITH table1 AS (SELECT 123 License_num, '123_1' license_line_num FROM dual UNION ALL
                SELECT 123 License_num, '123_2' license_line_num FROM dual UNION ALL
                SELECT 456 License_num, '456_1' license_line_num FROM dual UNION ALL
                SELECT 456 License_num, '456_2' license_line_num FROM dual),
     table2 AS (SELECT '123_1' license_line_num, 'XXX' item_num FROM dual UNION ALL
                SELECT '456_1' license_line_num, 'YYY' item_num FROM dual UNION ALL
                SELECT '456_2' license_line_num, 'ZZZ' item_num FROM dual)
SELECT t1.license_num,
       t1.license_line_num,
       MIN(CASE WHEN t2.license_line_num IS NULL THEN 0 ELSE 1 END) OVER (PARTITION BY t1.license_num) all_lines_present
FROM   table1 t1
       LEFT OUTER JOIN table2 t2 ON t1.license_line_num = t2.license_line_num
ORDER BY t1.license_num, t1.license_line_num;

LICENSE_NUM LICENSE_LINE_NUM ALL_LINES_PRESENT
----------- ---------------- -----------------
        123 123_1                            0
        123 123_2                            0
        456 456_1                            1
        456 456_2                            1

我假设在table2上有一个唯一约束,每个license_line_num最多只能有一行。

这通过将第二个表外连接到第一个表(它不应该产生任何重复的行)来工作。然后我们使用条件聚合函数(在本例中为MIN)来确定如果存在第二个表中的值,我们输出1,否则为每行输出0,然后找到最低值。

这样,如果任何行缺少项行,则每个license_num的所有行的最小值将为0.

ETA:如果你只想要每个license_num一行,你可以使用条件聚合函数,例如:

WITH table1 AS (SELECT 123 License_num, '123_1' license_line_num FROM dual UNION ALL
                SELECT 123 License_num, '123_2' license_line_num FROM dual UNION ALL
                SELECT 456 License_num, '456_1' license_line_num FROM dual UNION ALL
                SELECT 456 License_num, '456_2' license_line_num FROM dual),
     table2 AS (SELECT '123_1' license_line_num, 'XXX' item_num FROM dual UNION ALL
                SELECT '456_1' license_line_num, 'YYY' item_num FROM dual UNION ALL
                SELECT '456_2' license_line_num, 'ZZZ' item_num FROM dual)
SELECT license_num,
       CASE WHEN all_lines_present = 1 THEN 1 END all_lines_present
FROM   (SELECT t1.license_num,
               MIN(CASE WHEN t2.license_line_num IS NULL THEN 0 ELSE 1 END) all_lines_present
        FROM   table1 t1
               LEFT OUTER JOIN table2 t2 ON t1.license_line_num = t2.license_line_num
        GROUP BY t1.license_num)
ORDER BY license_num;

LICENSE_NUM ALL_LINES_PRESENT
----------- -----------------
        123 
        456                 1