Исключить набор из левого внешнего соединения - PullRequest
1 голос
/ 16 сентября 2009

Как исключить набор значений при использовании левого внешнего соединения?

Рассмотрим следующий запрос:

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.

Есть ли какие-либо идеи о том, как сопоставлять NULL коды зон инцидентов, исключая данный набор кодов регионов, без использования PL / SQL?

Обновление 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 ]

4 голосов
/ 16 сентября 2009

Кажется, проблема в том, что IN удаляет все коды области, которые имеют значение NULL.

Дайте попробовать:

    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)

Должен дать желаемый результат ...

0 голосов
/ 16 сентября 2009

Я не уверен, что понимаю вопрос, но если вы хотите получить значения 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')
0 голосов
/ 16 сентября 2009

Синтаксис выглядит правильно. Вы должны проверить свои данные, чтобы убедиться, что вы в здравом уме. Попробуйте это:

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

Это сообщит вам, есть ли у вас какие-либо инциденты, в которых площадь не представлена ​​в таблице областей.

0 голосов
/ 16 сентября 2009
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
0 голосов
/ 16 сентября 2009

Не могли бы вы попробовать:

   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')
0 голосов
/ 16 сентября 2009

Я не уверен на 100%, но, возможно, вы присоединяетесь к l.area_code для area.code когда вы должны присоединиться к area_code по l.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')
0 голосов
/ 16 сентября 2009

Я думаю, я бы попробовал это:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...