SQL Server INNER JOIN с нулевым значением и пересечением

У меня проблема. У меня есть две таблицы с одинаковыми столбцами. Я хочу создать третью таблицу, в которой будут строки идентификаторов из этих двух таблиц, где четыре выбранных столбца будут одинаковыми.

Я решил проблему со сравнением данных null с isnull.

Я написал что-то вроде этого:

WITH cteCandidates (City, Street, HouseNumber, PostCode)
  AS
  (
    SELECT City, Street, HouseNumber, PostCode
    FROM Gymnasium
    INTERSECT
    SELECT City, Street, HouseNumber, PostCode
    FROM PrimarySchool
  ) 
  select e.Id as 'Gymnasium',
  p.Id as 'PrimarySchool'
FROM
  Gymnasium AS e
Inner join cteCandidates AS c
    on isnull(e.City       ,'999999') = isnull(c.City       ,'999999')
   AND isnull(e.Street     ,'999999') = isnull(c.Street     ,'999999')
   AND isnull(e.HouseNumber,'999999') = isnull(c.HouseNumber,'999999')
   AND isnull(e.PostCode   ,'999999') = isnull(c.PostCode   ,'999999')
inner join PrimarySchool as p 
    on isnull(e.City       ,'999999') = isnull(p.City       ,'999999')
   AND isnull(e.Street     ,'999999') = isnull(p.Street     ,'999999')
   AND isnull(e.HouseNumber,'999999') = isnull(p.HouseNumber,'999999')
   AND isnull(e.PostCode   ,'999999') = isnull(p.PostCode   ,'999999')
order by PrimarySchool

Все работает нормально, кроме вот этого кода:

 SELECT City, Street, HouseNumber, PostCode
    FROM Gymnasium
    INTERSECT
    SELECT City, Street, HouseNumber, PostCode
    FROM PrimarySchool

вернул другое количество строк, чем первый код.

Что я делаю неправильно?


person Jakub Dropia    schedule 27.03.2012    source источник


Ответы (2)


Это можно объяснить только дублированием столбцов (Город, Улица, Номер дома, Почтовый индекс). Intersect вернет ровно one строку для всех дублированных данных, но внутреннее соединение создаст n*m совпадающих строк. Не могли бы вы проверить, что эти четыре столбца уникальны как в гимназии, так и в начальной школе?

person Nikola Markovinović    schedule 27.03.2012
comment
Ты был прав. У меня есть повторяющиеся строки в этих таблицах. Спасибо за ответ! - person Jakub Dropia; 03.04.2012

Единственное, что вы делаете неправильно, это то, что вы ожидаете, что два запроса вернут одинаковое количество строк.

В первом вы заменяете нули на «999999», а затем сравниваете полученное значение. Это делает все нулевые значения равными всем другим нулевым значениям (и значению «999999», хотя, по-видимому, это значение не встречается).

Во втором запросе вы выполняете пересечение без замены нулей. NULL никогда не равен никакому другому значению (включая другие значения NULL), поэтому будет возвращено меньше строк.

person Chris Shain    schedule 27.03.2012
comment
Возможно, я не правильно это читаю, но я думаю, что это неправда. Цитата из MSDN: При сравнении строк для определения различных значений учитываются два значения NULL. равно.. Быстрый тест показывает, что будет возвращена строка: select 'a', null intersect select 'a', null - person Nikola Markovinović; 28.03.2012