首页 > 解决方案 > Oracle:确保 IN 运算符使用的每个值即使没有匹配数据也始终返回一行

问题描述

下面是我的 SQL 查询,用于查找是否有多个 ID 已下达特定订单。它将 2 个表连接在一起 -REQUESTCODE在一起以返回位于的项目名称CODE

SELECT GETCLIENT(a.CLI_ID,a.CLI_ID_SCH) AS Client, a.FILLER_FCTY AS Facility, a.FILLER_ORD AS OrderNumber, a.ORD_DATE AS DateTime, b.OBSC_DESC AS ItemName 
FROM REQUEST a, CODE b
WHERE a.SERV_ID = b.OBSID
AND GETCLIENT(a.CLI_ID,a.CLI_ID_SCH) IN
('AZZ1',
'BCA2',
'BDG3',
'BMZ4',
'BSH5',
'CAS6',
'CBW7')
AND FILLER_FCTY = 'TGY'
AND SERV_ID = '00034'
AND OBSC_DESC = 'Item A'
ORDER BY 1

上面的查询将返回前 6 个 ID(AZZ1、BCA2、BDG3、BMZ4、BSH5 和 CAS6)以及预期的结果,因为它们已经下过相关订单,但是,因为最后一个 ID CBW7从未下过任何与指定的项目编号和项目名称,不返回此 ID 的结果。

即使数据库上没有匹配项,如何使此 ID 或任何 ID 返回一行?我尝试使用OR GETCLIENT(a.CLI_ID,a.CLI_ID_SCH) IS NULL但仍然没有返回最后一个 ID 的行。

标签: sqloracle

解决方案


切勿FROM子句中使用逗号。 始终使用正确、明确、标准 JOIN的语法。

在你的情况下,你想要一个LEFT JOIN. 这有点复杂,部分原因是不清楚这些列的来源。您应该限定所有列引用。并且,使用有意义的表别名而不是任意字母。

所以,我认为这可以满足您的要求:

SELECT l.Client,
       r.FILLER_FCTY AS Facility, r.FILLER_ORD AS OrderNumber, r.ORD_DATE AS DateTime,
       c.OBSC_DESC AS ItemName 
FROM (SELECT 'AZZ1' as client FROM DUAL UNION ALL
      SELECT 'BCA2' FROM DUAL UNION ALL
      SELECT 'BDG3' FROM DUAL UNION ALL
      SELECT 'BMZ4' FROM DUAL UNION ALL
      SELECT 'BSH5' FROM DUAL UNION ALL
      SELECT 'CAS6' FROM DUAL UNION ALL
      SELECT 'CBW7' FROM DUAL
     ) l LEFT JOIN
     (REQUEST r JOIN
      CODE c
      ON r.SERV_ID = c.OBSID AND
         ?.FILLER_FCTY = 'TGY' AND
         ?.SERV_ID = '00034' AND
         ?.OBSC_DESC = 'Item A'
     )
     ON GETCLIENT(r.CLI_ID, r.CLI_ID_SCH) = L.CODE      
ORDER BY 1;

?用于表别名以标识列的来源。


推荐阅读