Ich habe ein einfaches Skript, das vier Zufallszahlen (1 bis 4) abruft und sich dann wieder zusammenfügt, um die passende database_id-Nummer zu erhalten. Wenn ich das Skript mit LEFT JOIN ausführe, erhalte ich jedes Mal vier Zeilen zurück (das erwartete Ergebnis). Wenn ich es jedoch mit einem INNER JOIN ausführe, erhalte ich eine unterschiedliche Anzahl von Zeilen - manchmal zwei, manchmal acht.
Logischerweise sollte es keinen Unterschied geben, da ich weiß, dass Zeilen mit den Datenbank-IDs 1 bis 4 in sys.databases vorhanden sind. Und da wir aus der Zufallszahltabelle mit vier Zeilen auswählen (im Gegensatz zum Beitritt), sollten niemals mehr als vier Zeilen zurückgegeben werden.
Dies tritt sowohl in SQL Server 2012 als auch in 2014 auf. Warum gibt INNER JOIN eine unterschiedliche Anzahl von Zeilen zurück?
/* 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()) ;
Ich denke, es funktioniert gut, weil es keinen Join für den Wert der nicht deterministischen Funktion gibt.