SQL Server INNER JOIN со значением NULL и пересекаются - PullRequest
0 голосов
/ 28 марта 2012

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

Я решил проблему со сравнением данных 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

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

Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 28 марта 2012

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

0 голосов
/ 28 марта 2012

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

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

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

...