левое внешнее соединение в t-sql
у меня есть следующие две таблицы. Я использую SQL Server 2008 R2
Create table #tmp1 (
a char(1)
)
Create table #tmp2 (
id int,
a char(1),
val int
)
insert #tmp1 values ('A')
insert #tmp1 values ('B')
insert #tmp1 values ('C')
insert #tmp2 values (1, 'A', 10)
insert #tmp2 values (1, 'B', 20)
insert #tmp2 values (2, 'A', 30)
insert #tmp2 values (2, 'C', 40)
select * from #tmp1 t1 left outer join #tmp2 t2 on t1.a = t2.a
order by t2.id
Это возвращает результирующий набор
A 1 A 10
B 1 B 20
C 2 C 40
A 2 A 30
Я хотел бы иметь следующий набор результатов
A 1 A 10
B 1 B 20
C 1 null null
A 2 A 30
B 2 null null
C 2 C 40
прямо сейчас я достигаю этого, создавая новую таблицу с перекрестным соединением, как это, а затем делая внешнее соединение
select * into #tmp3 from #tmp1 cross join (select distinct ID from #tmp2) t
select * from #tmp3 t1 left outer join #tmp2 t2 on t1.a = t2.a and t1.id = t2.id
есть ли лучший способ сделать это ?
спасибо
2 ответов
чтобы получить то, что вы хотите, вам нужно "управлять" стол. То есть, вы хотите полный список всех комбинаций, а затем присоединиться к другим таблицам, чтобы получить спички. Вот один из способов:
select t1.a, t2.*
from (select t1.a as a, t2.id as id
from (select distinct a from #tmp1 t1) t1
cross join
(select distinct id from #tmp2 t2) t2
) driving left outer join
#tmp1 t1
on t1.a = driving.a left outer join
#tmp2 t2
on t2.id = driving.id and
t2.a = driving.a
order by t2.id
то, что вы ищете, является декартовым произведением значений в #tbl1 и значений в столбце id в #tbl2. Потому что значения в #tbl2.id не уникальны. возможно, лучше иметь дополнительную таблицу со строкой для каждого #tbl2.значение id. Тогда вы можете использовать это решение:
Create table #tmp1 (
a char(1)
)
Create table #tmp2 (
id int,
a char(1),
val int
)
Create table #tmp3 (
id int
)
insert #tmp1 values ('A')
insert #tmp1 values ('B')
insert #tmp1 values ('C')
insert #tmp3 values (1)
insert #tmp3 values (2)
insert #tmp2 values (1, 'A', 10)
insert #tmp2 values (1, 'B', 20)
insert #tmp2 values (2, 'A', 30)
insert #tmp2 values (2, 'C', 40)
SELECT t3.id,t1.a,t2.val
FROM #tmp1 AS t1
CROSS JOIN #tmp3 AS t3
LEFT OUTER JOIN #tmp2 AS t2
ON t1.a = t2.a AND t3.id = t2.id
ORDER BY t3.id, t1.a;
Если это не вариант, используйте это вместо этого:
SELECT t3.id,t1.a,t2.val
FROM #tmp1 AS t1
CROSS JOIN (SELECT DISTINCT id FROM #tmp2) AS t3
LEFT OUTER JOIN #tmp2 AS t2
ON t1.a = t2.a AND t3.id = t2.id
ORDER BY t3.id, t1.a;