Ho un semplice script che ottiene quattro numeri casuali (da 1 a 4) e poi si unisce per ottenere il numero database_id corrispondente. Quando eseguo lo script con un JOIN SINISTRO, ottengo quattro righe indietro ogni volta (il risultato previsto). Tuttavia, quando lo eseguo con un INNER JOIN, ottengo un numero variabile di righe - a volte due, a volte otto.
Logicamente, non dovrebbe esserci alcuna differenza perché so che esistono file con database_ids 1-4 nei database sys.d. E poiché stiamo selezionando dalla tabella dei numeri casuali con quattro righe (anziché unirci ad essa), non dovrebbero mai esserci più di quattro righe restituite.
Ciò accade in SQL Server 2012 e 2014. Cosa sta causando INNER JOIN per restituire un numero variabile di righe?
/* Works as expected -- always four rows */
SELECT rando.RandomNumber, d.database_id
FROM
(SELECT 1 + ABS(CHECKSUM(NEWID())) % (4) AS RandomNumber
FROM sys.databases WHERE database_id <= 4) AS rando
LEFT JOIN sys.databases d ON rando.RandomNumber = d.database_id;
/* Returns a varying number of rows */
SELECT rando.RandomNumber, d.database_id
FROM
(SELECT 1 + ABS(CHECKSUM(NEWID())) % (4) AS RandomNumber
FROM sys.databases WHERE database_id <= 4) AS rando
INNER JOIN sys.databases d ON rando.RandomNumber = d.database_id;
/* Also returns a varying number of rows */
WITH rando AS (
SELECT 1 + ABS(CHECKSUM(NEWID())) % (4) AS RandomNumber
FROM sys.databases WHERE database_id <= 4
)
SELECT r.RandomNumber, d.database_id
FROM rando AS r
INNER JOIN sys.databases d ON r.RandomNumber = d.database_id;
SELECT TOP (4) d.database_id FROM sys.databases AS d CROSS JOIN (VALUES (1),(2),(3),(4)) AS multi (i) WHERE d.database_id <= 4 ORDER BY CHECKSUM(NEWID()) ;
immagino che funzioni bene perché non esiste un join sul valore della funzione non deterministica.