You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何过滤UNION查询结果:排除特定条件的第二查询记录

问题描述

我有一个包含两个UNION ALL子查询的SQL语句,当前查询结果如下:

ITEM_NUMBER SUBINVENTORY_CODE   INV_LOCATOR     QUERY       IVT_SEQNUM  PRIORITY    OVERALL_PRIORITY
12923       41OPR               Z-B-01-02-C     1st Query   1           1           1
12923       41OPR               W-130-00-00-00  1st Query   2           1           2
12923       11OPR               AAAAAAA         2nd Query   1           2           1
12923       41OPR               AAAAAAA         2nd Query   1           2           1

需要排除的记录:第二查询中,与第一查询存在相同ITEM_NUMBER和SUBINVENTORY_CODE,且INV_LOCATOR值为'AAAAAAA'的记录。期望结果如下:

ITEM_NUMBER SUBINVENTORY_CODE   INV_LOCATOR     QUERY       IVT_SEQNUM  PRIORITY    OVERALL_PRIORITY
12923       41OPR               Z-B-01-02-C     1st Query   1           1           1
12923       41OPR               W-130-00-00-00  1st Query   2           1           2
12923       11OPR               AAAAAAA         2nd Query   1           2           1
尝试过的SQL代码

我尝试使用ROW_NUMBER分析窗口函数和cnt_first_query分析函数,但未能得到正确结果,当前代码如下:

SELECT * FROM
(SELECT item_number, subinventory_code, INV_LOCATOR, QUERY, ivt_seqnum, priority, ROW_NUMBER() OVER (PARTITION BY  priority, subinventory_code  ORDER BY  priority, subinventory_code  ) Overall_Priority 
  ,COUNT(CASE WHEN priority = 1 THEN 1 END) OVER (PARTITION BY item_number, subinventory_code) as cnt_first_query
  FROM
(SELECT ESI.item_number,  IOQD.subinventory_code  SUBINVENTORY_CODE, 

ROW_NUMBER() OVER (PARTITION BY ESI.item_number , IOQD.subinventory_code  
ORDER BY ESI.item_number, IOQD.subinventory_code ) ivt_seqnum
                
 ,LOC.SEGMENT1||'-'||LOC.SEGMENT2||'-'||LOC.SEGMENT3||'-'||LOC.SEGMENT4||'-'||LOC.SEGMENT5 INV_LOCATOR, 1 as priority, '1st Query' AS QUERY            --, ioqd.locator_id
 
 
 
FROM egp_system_items ESI, inv_onhand_quantities_detail IOQD, inv_item_locations LOC
WHERE ESI.INVENTORY_ITEM_ID = 100000110904412
AND ioqd.subinventory_code = '41OPR'
AND IOQD.inventory_item_id = ESI.inventory_item_id
and IOQD.organization_id = esi.organization_id
AND LOC.inventory_location_id = ioqd.locator_id

UNION ALL



SELECT ESI.item_number, decode(substr(IOQD.secondary_inventory,1,3),                                  
                                                              '11C','11CCL'
                                                              ,'11O','11OPR'
                                                              ,'18O','18OPR'
                                                              ,'41S','24000'
                                                              ,'41O','41OPR'
                                                              ,'60O','60OPR'
                                                              ,'70O','70OPR'
                                                              ,'70C','70CCL'
                                                              ,'70M', '70OPR'
                                                              ,IOQD.secondary_inventory) subinventory_code, 

ROW_NUMBER() OVER (PARTITION BY ESI.item_number , IOQD.secondary_inventory  
ORDER BY ESI.item_number, IOQD.secondary_inventory ) ivt_seqnum , 
                
case when 
 (SELECT iil.SEGMENT1||'-'||iil.SEGMENT2||'-'||iil.SEGMENT3||'-'||iil.SEGMENT4||'-'||iil.SEGMENT5
           FROM inv_item_loc_defaults iild, 
                inv_item_locations iil
          WHERE iild.inventory_item_id = esi.inventory_item_id
            AND iild.subinventory_code = IOQD.secondary_inventory
            AND iild.locator_id       = iil.inventory_location_id
            AND rownum= 1 and length(Segment1) >= 1 ) is not null 
then (SELECT iil.SEGMENT1||'-'||iil.SEGMENT2||'-'||iil.SEGMENT3||'-'||iil.SEGMENT4||'-'||iil.SEGMENT5
           FROM inv_item_loc_defaults iild, 
                inv_item_locations iil
          WHERE iild.inventory_item_id = esi.inventory_item_id
            AND iild.subinventory_code = IOQD.secondary_inventory
            AND iild.locator_id       = iil.inventory_location_id
            AND rownum= 1 and length(Segment1) >= 1 )   

when (SELECT iil.SEGMENT1||'-'||iil.SEGMENT2||'-'||iil.SEGMENT3||'-'||iil.SEGMENT4||'-'||iil.SEGMENT5
           FROM inv_secondary_locators iild, 
                inv_item_locations iil
          WHERE iild.inventory_item_id = esi.inventory_item_id
            AND iild.subinventory_code = IOQD.secondary_inventory
            AND iild.SECONDARY_LOCATOR= iil.inventory_location_id
            AND rownum = 1 and length(Segment1) >= 1 ) is not null 
        Then (SELECT iil.SEGMENT1||'-'||iil.SEGMENT2||'-'||iil.SEGMENT3||'-'||iil.SEGMENT4||'-'||iil.SEGMENT5
           FROM inv_secondary_locators iild, 
                inv_item_locations iil
          WHERE iild.inventory_item_id = esi.inventory_item_id
            AND iild.subinventory_code = IOQD.secondary_inventory
            AND iild.SECONDARY_LOCATOR= iil.inventory_location_id
            AND rownum = 1 and length(Segment1) >= 1 )

Else 'AAAAAAA'
END as      INV_LOCATOR   , 2 as priority  , '2nd Query' AS QUERY  
                
FROM egp_system_items ESI, INV_ITEM_SUB_INVENTORIES IOQD --,  inv_item_loc_defaults iild, inv_item_locations iil
WHERE IOQD.inventory_item_id = ESI.inventory_item_id
AND IOQD.organization_id = ESI.organization_id
AND ESI.INVENTORY_ITEM_ID = 100000110904412
--AND iild.inventory_item_id = esi.inventory_item_id
--AND iild.subinventory_code = IOQD.secondary_inventory
--AND iild.locator_id  = iil.inventory_location_id 

) --WHERE (priority <> 2 AND INV_LOCATOR <> 'AAAAAAA') 
)    --WHERE (INV_LOCATOR <> 'AAAAAAA' AND OVERALL_PRIORITY <=1)


WHERE NOT cnt_first_query > 0 AND INV_LOCATOR = 'AAAAAAA'
解决方案

原SQL的过滤条件逻辑错误,NOT cnt_first_query > 0会排除所有在第一查询中存在对应ITEM_NUMBER和SUBINVENTORY_CODE的记录,而非仅排除第二查询中符合条件的特定记录。以下是修正后的SQL:

SELECT item_number, subinventory_code, INV_LOCATOR, QUERY, ivt_seqnum, priority, Overall_Priority
FROM
(
    SELECT 
        item_number, 
        subinventory_code, 
        INV_LOCATOR, 
        QUERY, 
        ivt_seqnum, 
        priority, 
        ROW_NUMBER() OVER (PARTITION BY priority, subinventory_code ORDER BY priority, subinventory_code) Overall_Priority,
        -- 标记当前(item_number, subinventory_code)是否在第一查询中存在
        MAX(CASE WHEN priority = 1 THEN 1 ELSE 0 END) OVER (PARTITION BY item_number, subinventory_code) AS exists_in_first_query
    FROM
    (
        -- 第一查询部分
        SELECT 
            ESI.item_number, 
            IOQD.subinventory_code SUBINVENTORY_CODE,
            ROW_NUMBER() OVER (PARTITION BY ESI.item_number, IOQD.subinventory_code ORDER BY ESI.item_number, IOQD.subinventory_code) ivt_seqnum,
            LOC.SEGMENT1||'-'||LOC.SEGMENT2||'-'||LOC.SEGMENT3||'-'||LOC.SEGMENT4||'-'||LOC.SEGMENT5 INV_LOCATOR, 
            1 as priority, 
            '1st Query' AS QUERY
        FROM egp_system_items ESI
        JOIN inv_onhand_quantities_detail IOQD ON IOQD.inventory_item_id = ESI.inventory_item_id AND IOQD.organization_id = esi.organization_id
        JOIN inv_item_locations LOC ON LOC.inventory_location_id = ioqd.locator_id
        WHERE ESI.INVENTORY_ITEM_ID = 100000110904412
          AND ioqd.subinventory_code = '41OPR'

        UNION ALL

        -- 第二查询部分
        SELECT 
            ESI.item_number, 
            decode(substr(IOQD.secondary_inventory,1,3),                                  
                '11C','11CCL',
                '11O','11OPR',
                '18O','18OPR',
                '41S','24000',
                '41O','41OPR',
                '60O','60OPR',
                '70O','70OPR',
                '70C','70CCL',
                '70M', '70OPR',
                IOQD.secondary_inventory) subinventory_code, 
            ROW_NUMBER() OVER (PARTITION BY ESI.item_number, IOQD.secondary_inventory ORDER BY ESI.item_number, IOQD.secondary_inventory) ivt_seqnum, 
            CASE 
                WHEN (
                    SELECT iil.SEGMENT1||'-'||iil.SEGMENT2||'-'||iil.SEGMENT3||'-'||iil.SEGMENT4||'-'||iil.SEGMENT5
                    FROM inv_item_loc_defaults iild
                    JOIN inv_item_locations iil ON iild.locator_id = iil.inventory_location_id
                    WHERE iild.inventory_item_id = esi.inventory_item_id
                      AND iild.subinventory_code = IOQD.secondary_inventory
                      AND length(iil.Segment1) >= 1
                      AND rownum=1
                ) IS NOT NULL 
                THEN (
                    SELECT iil.SEGMENT1||'-'||iil.SEGMENT2||'-'||iil.SEGMENT3||'-'||iil.SEGMENT4||'-'||iil.SEGMENT5
                    FROM inv_item_loc_defaults iild
                    JOIN inv_item_locations iil ON iild.locator_id = iil.inventory_location_id
                    WHERE iild.inventory_item_id = esi.inventory_item_id
                      AND iild.subinventory_code = IOQD.secondary_inventory
                      AND length(iil.Segment1) >= 1
                      AND rownum=1
                )
                WHEN (
                    SELECT iil.SEGMENT1||'-'||iil.SEGMENT2||'-'||iil.SEGMENT3||'-'||iil.SEGMENT4||'-'||iil.SEGMENT5
                    FROM inv_secondary_locators iild
                    JOIN inv_item_locations iil ON iild.SECONDARY_LOCATOR = iil.inventory_location_id
                    WHERE iild.inventory_item_id = esi.inventory_item_id
                      AND iild.subinventory_code = IOQD.secondary_inventory
                      AND length(iil.Segment1) >= 1
                      AND rownum=1
                ) IS NOT NULL
                THEN (
                    SELECT iil.SEGMENT1||'-'||iil.SEGMENT2||'-'||iil.SEGMENT3||'-'||iil.SEGMENT4||'-'||iil.SEGMENT5
                    FROM inv_secondary_locators iild
                    JOIN inv_item_locations iil ON iild.SECONDARY_LOCATOR = iil.inventory_location_id
                    WHERE iild.inventory_item_id = esi.inventory_item_id
                      AND iild.subinventory_code = IOQD.secondary_inventory
                      AND length(iil.Segment1) >= 1
                      AND rownum=1
                )
                ELSE 'AAAAAAA'
            END as INV_LOCATOR, 
            2 as priority, 
            '2nd Query' AS QUERY  
        FROM egp_system_items ESI
        JOIN INV_ITEM_SUB_INVENTORIES IOQD ON IOQD.inventory_item_id = ESI.inventory_item_id AND IOQD.organization_id = ESI.organization_id
        WHERE ESI.INVENTORY_ITEM_ID = 100000110904412
    ) t1
) t2
-- 精准排除不符合要求的记录
WHERE NOT (priority = 2 AND INV_LOCATOR = 'AAAAAAA' AND exists_in_first_query = 1);

关键修改点

  1. 用MAX(CASE WHEN priority=1 THEN 1 ELSE 0 END)窗口函数标记每个(item_number, subinventory_code)是否在第一查询中存在,替代原有的cnt_first_query。
  2. 外层过滤条件调整为NOT (priority = 2 AND INV_LOCATOR = 'AAAAAAA' AND exists_in_first_query = 1),仅排除目标记录。
  3. 将隐式JOIN改为显式JOIN,提升代码可读性。

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 07:59:52