It's OK for nested subqueries to use the same aliases as used in the parent query, although it might be a bit confusing for someone reading the code. The name space for aliases on a nested subquery is separate from the name space on the parent. For example the query below has a nested subquery b
that also has an alias b
used within it. This would be potentially confusing to the programmer but fine with the DBMS engine:
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
On a correlated subquery you have access to the parent's aliases, so the aliases must be unique across the parent query and correlated subquery. If we take a correlated subquery such as the one below we have a single, global name space shared between the parent query and the correlated subquery:
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)
The correlated subquery does not have an alias as it does not participate in a join as such1. The references b
and b2
for bar
are both available to the subquery as correlated subqueries share their namespace for aliases with the parent.
1 Note that the optimiser may choose to use join operators within the plan behind the scenes, although the actual operation specified is a correlated subquery and not a join against a nested subquery.
A selective index will not be used when using query
to retrieve the data.
From Selective XML Indexes (SXI) - Supported XML Features
Selective XML indexes support the XQuery supported by SQL Server
inside the exist(), value() and nodes() methods.
For the query() and modify() methods, selective XML indexes may be
used for node filtering only.
For the query() method, selective XML indexes are not used to retrieve
results.
However testing shows that the index is used when you rewrite the query using nodes. These queries returns the same but the second is faster because it uses the the selective XML index.
select data.query('/Log/CallStack/ExceptionThread/Line')
from LogData
select T.X.query('.')
from LogData
cross apply data.nodes('/Log/CallStack/ExceptionThread/Line') as T(X)
The selective XML index used in the second query is defined as..
[Line] = '/Log/CallStack/ExceptionThread/Line' as XQUERY 'node()',
I used a table of my own just to be able to show what the difference in this case is.
(67992 row(s) affected)
Table 'LogData'. Scan count 1, logical reads 388, physical reads 0, read-ahead reads 0, lob logical reads 1840865, lob physical reads 313514, lob read-ahead reads 24.
SQL Server Execution Times:
CPU time = 129792 ms, elapsed time = 180087 ms.
(1850106 row(s) affected)
Table 'xml_sxi_table_622625261_256000'. Scan count 1, logical reads 8416, physical reads 3, read-ahead reads 8403, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LogData'. Scan count 1, logical reads 388, physical reads 0, read-ahead reads 0, lob logical reads 927882, lob physical reads 0, lob read-ahead reads 24.
SQL Server Execution Times:
CPU time = 65271 ms, elapsed time = 67636 ms.
Best Answer
By default the SQL Server does not create a node for NULL values so if you change your query to use two CASE statements and return NULL when there is no match you will get the XML you are looking for.
dbfiddle