从左外连接中排除设置

时间:2009-09-16 18:13:07

标签: sql oracle plsql

使用左外连接时如何排除一组值?

考虑以下问题:

SELECT i.id,
       i.location,
       area.description
  FROM incident_vw i,
       area_vw area
 WHERE i.area_code = area.code(+)
   AND i.area_code NOT IN ('T20', 'V20B', 'V20O', 'V20P')

执行查询,但不显示任何NULL区域代码值。

BE AWARE INCIDENT_VW.area_code可以且确实有NULL值。

如何在不使用PL / SQL的情况下排除给定区域代码集的情况下如何匹配NULL事件区域代码?

ANSI更新

使用等效的ANSI SQL也不起作用:

    SELECT i.id,
           i.location,
           area.description
      FROM incident_vw i
 LEFT JOIN area_vw area
        ON area.code = i.area_code
     WHERE i.area_code NOT IN ('T20', 'V20B', 'V20O', 'V20P')

解决方案

这有效:

SELECT i.id,
       i.location,
       area.description
  FROM incident_vw i,
       area_vw area
 WHERE i.area_code = area.code(+)
   AND (i.area_code NOT IN ('T20', 'V20B', 'V20O', 'V20P') and i.area_code IS NULL)

谢谢大家!

7 个答案:

答案 0 :(得分:4)

似乎问题是IN正在删除所有为NULL的area_codes。

尝试一下:

    SELECT i.id,
           i.location,
           area.description
      FROM incident_vw i
 LEFT JOIN area_vw area
        ON area.code = i.area_code
     WHERE (i.area_code NOT IN ('T20', 'V20B', 'V20O', 'V20P')
            OR i.area_code IS NULL)

应该给出理想的结果......

答案 1 :(得分:0)

我想我会试试这个:

SELECT i.id,
       i.location,
       area.description
  FROM (SELECT *
          FROM incident_vw
         WHERE i.area_code NOT IN ('T20', 'V20B', 'V20O', 'V20P')
            OR i.area_code IS NULL) i
     , area_vw area
 WHERE i.area_code = area.code (+)

或ANSI等价物:

   SELECT i.id,
          i.location,
          area.description
     FROM (SELECT *
             FROM incident_vw
            WHERE i.area_code NOT IN ('T20', 'V20B', 'V20O', 'V20P')
               OR i.area_code IS NULL) i
LEFT JOIN area_vw area
       ON i.area_code = area.code

答案 2 :(得分:0)

我不是100%肯定,但也许你正在加入area.code上的l.area_code 当你应该加入l.area.code上的area_code时。

SELECT i.id,
       i.location,
       area.description
  FROM incident_vw i,
       area_vw area
 WHERE 1=1
   AND i.area_code = area.code(+)
   AND i.area_code NOT IN ('T20', 'V20B', 'V20O', 'V20P')

应该是:

SELECT i.id,
       i.location,
       area.description
  FROM incident_vw i,
       area_vw area
 WHERE 1=1
   AND i.area_code(+) = area.code
   AND i.area_code NOT IN ('T20', 'V20B', 'V20O', 'V20P')

答案 3 :(得分:0)

你可以尝试一下:

   SELECT i.id,
           i.location,
           area.description
      FROM incident_vw i
 LEFT JOIN area_vw area
        ON area.code = i.area_code
     WHERE NVL(i.area_code,'something') NOT IN ('T20', 'V20B', 'V20O', 'V20P')

答案 4 :(得分:0)

SELECT i.id,
       i.location,
       area.description
  FROM incident_vw i
  LEFT JOIN area_vw area
    ON i.area_code = area.code
  WHERE i.area_code NOT IN ('T20', 'V20B', 'V20O', 'V20P')
UNION
SELECT i.id,
       i.location,
       NULL as description
   FROM incident_vw i
   WHERE i.area_code IS NULL

答案 5 :(得分:0)

语法看起来正确。您应该测试您的数据以确保您的理智。试试这个:

SELECT count(*) 
FROM  incident_vw i
WHERE i.area_code NOT IN 
      (SELECT a.area_code 
       FROM area_vw a);

这将告诉您是否有任何事件没有区域表中的区域。

答案 6 :(得分:0)

我不确定我是否理解这个问题,但如果您想在排除列表中获取区域代码的NULL,那么只需将您的条件从WHERE移动到JOIN条件:

    SELECT i.id,
           i.location,
           area.description
      FROM incident_vw i
 LEFT JOIN area_vw area
        ON area.code = i.area_code
       AND area.code NOT IN ('T20', 'V20B', 'V20O', 'V20P')