Salve,
ridotto all'osso, il comando eseguito diventa
SELECT ROW_NUMBER() OVER (ORDER BY a.[cod]) AS [rn]
, a.[cod]
, b.[data]
FROM @t1 a
JOIN @t2 b ON a.[cod] = b.[cod] OR a.[alias] = b.[cod]
GROUP BY a.[cod], b.[data]
ORDER BY a.cod;
che ti ritorna il risultato desiderato, mentre tu preferiresti
SELECT ROW_NUMBER() OVER (ORDER BY a.[cod]) AS [rn]
, a.[cod]
, b.[data]
FROM @t1 a
JOIN @t2 b ON a.[cod] = b.[cod]
JOIN @t2 c ON a.[alias] = c.[cod]
GROUP BY a.[cod], b.[data]
ORDER BY a.cod;
ma non ottieni il risultato sperato per il semplice principio di funzionamento della JOIN, che esclude dal risultato quanto non contrapponibile....
potresti eventualmente "risolvere" diversamente con una UNION, che utilizzata con una common table expression ti diventerebbe simile a
WITH cte AS (
SELECT a.[cod]
, b.[data]
FROM @t1 a
JOIN @t2 b ON a.[cod] = b.[cod]
UNION
SELECT a.[cod]
, b.[data]
FROM @t1 a
JOIN @t2 b ON a.[alias] = b.[cod]
)
SELECT ROW_NUMBER() OVER (ORDER BY c.[cod]) AS [rn]
, c.[cod]
, c.[data]
FROM cte c
GROUP BY c.[cod], c.[data]
ORDER BY c.cod;
ma i piani di esecuzione, al di la' ovviamente che lo scenario corrente che e' banlanlmente triviale (senza indici, pochi dati, ...), NON sono assolutamente rinfrancanti nella seconda ipotesi...
nel primo caso, quello originale, dove e' previsto
FROM @t1 a
JOIN @t2 b ON a.[cod] = b.[cod] OR a.[alias] = b.[cod]
, nella mia rappresentazione banale prevede 2 scan completi con un nested loop derivante dalla join... l'operatore OR in questo caso consente con semplicita' la risoluzione della lookup senza sforzi addizionali...
|--Sequence Project(DEFINE:([Expr1004]=row_number))
|--Segment
|--Sort(DISTINCT ORDER BY:([a].[cod] ASC, [b].[data] ASC))
|--Nested Loops(Inner Join, WHERE:(@t1.[cod] as [a].[cod]=@t2.[cod] as [b].[cod] OR @t1.[alias] as [a].[alias]=@t2.[cod] as [b].[cod]))
|--Table Scan(OBJECT:(@t2 AS [b]))
|--Table Scan(OBJECT:(@t1 AS [a]))
l'utilizzo della UNION, dove ci sono 2 set filtrati, uno per il confronto su [cod] e l'altro per il confronto su [alias]
FROM @t1 a
JOIN @t2 b ON a.[cod] = b.[cod]
UNION ...
FROM @t1 a
JOIN @t2 b ON a.[alias] = b.[cod];
prevede ulteriori passaggi intermedi, sempre in questo scenario banale, oltre alla lookup eseguita con un nested loop (JOIN di cui sopra ma qui comunque funzionale ed utilizzata), richiedendo anche l'hash match della UNION
|--Sequence Project(DEFINE:([Expr1010]=row_number))
|--Segment
|--Sort(DISTINCT ORDER BY:([Union1008] ASC, [Union1009] ASC))
|--Concatenation
|--Nested Loops(Inner Join, WHERE:(@t2.[cod] as [b].[cod]=@t1.[cod] as [a].[cod]))
| |--Sort(ORDER BY:([b].[cod] ASC, [b].[data] ASC))
| | |--Table Scan(OBJECT:(@t2 AS [b]))
| |--Table Scan(OBJECT:(@t1 AS [a]))
|--Hash Match(Inner Join, HASH:([a].[alias])=([b].[cod]), RESIDUAL:(@t2.[cod] as [b].[cod]=@t1.[alias] as [a].[alias]))
|--Table Scan(OBJECT:(@t1 AS [a]))
|--Table Scan(OBJECT:(@t2 AS [b]))
cosa non ti piace nel tuo codice originario, al di la' della "brutta abitudine" di utilizzo di un "alias" sulla chiave di riferimento alla tabella esterna?
salutoni romagnoli
--
Andrea