Mám dotaz SQL, jehož aliasy jsou stejné jako některé jeho aliasy jeho poddotazu.
Například:
select *
from ROOM r
where ...
(
select *
from ROAD r
where ...
)
Funguje to dobře, protože alias poddotazu zřejmě skrývá hlavní.
r
hlavního dotazu?Je v pořádku, aby vnořené poddotazy používaly stejné aliasy, jaké byly použity v nadřazeném dotazu, i když to může být pro někoho, kdo čte kód, matoucí. Jmenný prostor pro aliasy vnořeného poddotazu je oddělený od jmenného prostoru nadřazeného. Například dotaz níže obsahuje vnořený poddotaz b
, který také obsahuje alias b
. To by bylo potenciálně matoucí pro programátora, ale v pořádku s motorem DBMS:
select a.foo
,b.bar
,b.BarCount
from (select b.bar
,count (*) as BarCount
from BarTable b
join OtherTable o
on b.OtherTableID = o.OtherTableID
group by b.bar) b
join Foobar a
on a.bar = b.bar
Na korelovaném poddotazu máte přístup k aliasu nadřazeného prvku, takže aliasy musí být jedinečné v nadřazeném dotazu a korelovaném poddotazu. Vezmeme-li korelovaný poddotaz, jako je pod, máme jediný, globální jmenný prostor sdílený mezi nadřazeným dotazem a korelovaným poddotazem:
select a.foo
,b.bar
from Foobar a
join Bar b
on b.FooBarID = a.FooBarID
where not exists
(select 1
from Bar b2
where b2.BarCategoryID = b.BarCategoryID
and b2.BarDate > b.BarDate)
Korelovaný dílčí dotaz nemá alias, protože se neúčastní spojení jako takového1. Odkazy b
a b2
pro bar
jsou oba k dispozici pro poddotaz, protože korelované poddotazy sdílejí svůj jmenný prostor pro aliasy s nadřazeným.
1 Všimněte si, že optimalizátor se může rozhodnout použít operátory spojení v rámci plánu v zákulisí, i když skutečnou zadanou operací je korelovaný poddotaz a nikoli spojení proti vnořenému poddotazu.
ConcernedOfTunbridgeWells, píšete (důrazný důl): "Na korelovaný poddotaz máte přístup k aliasu rodičů, takže aliasy musí být jedinečný v nadřazeném dotazu a korelovaném poddotazu. “
Nevěřím, že je vyžadována jedinečnost. Věřím, že pokud se alias použije v korelovaném poddotazu jako název korelace, stejně jako alias tabulky ve vnějším dotazu, bude mít přednost alias v poddotazu.
Příklad:
CREATE TABLE #T (A INT)
CREATE TABLE #U (A INT)
CREATE TABLE #V (A INT)
INSERT INTO #T (A) VALUES (1), (2), (3)
INSERT INTO #U (A) VALUES (2), (3), (4)
INSERT INTO #V (A) VALUES (3), (4), (5)
SELECT
T1.A
FROM
#T AS T1
INNER JOIN #U AS T2 ON T1.A = T2.A
WHERE
EXISTS (SELECT * FROM #V AS T2 WHERE T1.A = T2.A)
Výstup je "3": tabulky T a U mají společné 2 a 3, ale predikát WHERE
dále filtruje řádky vrácené na 3 a 2 neexistují ve V.