我需要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执行此操作?有什么建议吗?
由于
答案 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