Избегайте перекрестных объединений в SQL Server - PullRequest
0 голосов
/ 08 июня 2018

У меня есть 2 таблицы T1 и T2.

T1 :

ID  |   Name                              
----+-------
A   |   A1                                
A   |   C1

T2 :

ID   | Name
-----+------
A    | A1
A    | B1

Я хочу получить записи с одинаковыми идентификатором и именем с флагом 1 и одинаковым идентификатором и с другим именем с флагом 0. Однако при объединении таблицы в SQL Server я получаю перекрестное объединение:

A | A1 | A1 | 1                 
A | A1 | B1 | 0  
A | C1 | A1 | 0  
A | C1 | B1 | 0

Но мне нужен ответ:

A | A1 | A1 | 1     
A | C1 | B1 | 0

Приведенный выше результат дает мне ту же информацию о несоответствии имен, но в ограниченном количестве нет.строк и без повторений.

Может кто-нибудь дать мне знать, как это можно сделать в SQL Server?

Ответы [ 3 ]

0 голосов
/ 10 июня 2018

Используйте объединение для простоты:

select T1.ID, T1.Name Name1, T2.Name Name2, 1 flag
from T1
join T2 on T1.ID = T2.ID
and T1.Name = T2.Name
union all
select T1.ID, T1.Name, T2.Name, 0
from T1
join T2 on T1.ID = T2.ID
and T1.Name != T2.Name

Использование объединения не является наиболее эффективным способом, но его гораздо проще понять, и если у вас нет миллионов строк,он все равно будет работать очень быстро (а union all немного быстрее, чем union)

0 голосов
/ 19 июня 2018

вы можете использовать ROW_NUMBER и FULL JOIN

DECLARE @T1 TABLE (ID VARCHAR(5),   Name VARCHAR(5))
INSERT INTO @T1 VALUES ('A', 'A1')
INSERT INTO @T1 VALUES('A', 'C1')

DECLARE @T2 TABLE (ID VARCHAR(5),   Name VARCHAR(5))
INSERT INTO @T2 VALUES ('A', 'A1')
INSERT INTO @T2 VALUES ('A', 'B1')


SELECT T1.ID, T1.Name, T2.Name, CASE WHEN T1.Name = T2.Name THEN 1 ELSE 0 END
FROM 
    ( SELECT ROW_NUMBER()OVER(PARTITION BY ID ORDER BY Name) AS RN, * FROM @T1 ) T1
    FULL JOIN 
    ( SELECT ROW_NUMBER()OVER(PARTITION BY ID ORDER BY Name) AS RN, * FROM @T2 ) T2 
        ON T1.ID = T2.ID AND T1.RN = T2.RN

Результат:

ID    Name  Name  
----- ----- ----- -----------
A     A1    A1    1
A     C1    B1    0
0 голосов
/ 09 июня 2018

Это то, что вы ищете:

SELECT T1.ID, T1.Name Name1, T2.Name Name2, case T1.Name when T2.Name then 1 else 0 end Result
from T1
inner join T2 on T1.ID = T2.ID
where T1.Name = T2.Name
    or (not exists (select 1 from T2 where T1.Name = Name and T1.ID = ID)
        and not exists (select 1 from T1 where T2.Name = Name and T2.ID = ID))
...