sobota, 1 lutego 2014

Cross join czy nie cross join

Tym razem kolejna zagadka z odpowiedzią. Mając poniższe tabele jak uzyskać iloczyn kartezjański.

Col1
1

Col2
a
b
c

set nocount on
 
declare @Table1 table (
    Col1 int
)
 
declare @Table2 table (
    Col2 char(1)
)
 
insert into @Table1 (Col1) values(1)
insert into @Table2 (Col2) values('a'), ('b'), ('c')
Najprostrzym rozwiązaniem jest po prostu użycie cross join.
select Col1, Col2 from @Table1, @Table2
Dużo osób zajmujących się relacyjnymi bazami danych nie bardzo ma pojęcie gdzie ten cross join można wykorzystać. Tak więc aby trochę skomplikować zadanie, chciałbym ten iloczyn kartezjański uzyskań korzystając z inner join.


Poniżej odpowiedź na tą łamigłowkę.
select Col1, Col2 from @Table1 inner join @Table2 on 1=1
Jednakże to nie wszystko. Bo ten sam wynik można uzyskać za pomocą left join i full outer join.
select Col1, Col2 from @Table1 left join @Table2 on 1=1
select Col1, Col2 from @Table1 full outer join @Table2 on 1=1
Co ciekawe pomimo tego, że zapytania zwracają ten sam wynik SQL Server wykonuje je w inny sposób. Jako ciekawostkę polecam przyjrzenie się właściwym planom wykonania i zwrócenie uwagi jaki operator złączenia jest wykorzystywany, jak także porównanie szacowanych wartości z tymi które rzeczywiście miały miejsce (Estimated vs Actual Number Of Rows oraz Estimated Number Of Executions vs Number Of Executions).