Saya memiliki skrip sederhana yang mendapat empat angka acak (1 hingga 4) dan kemudian bergabung kembali untuk mendapatkan nomor database_id yang cocok. Ketika saya menjalankan skrip dengan BERGABUNG KIRI, saya mendapatkan empat baris kembali setiap kali (hasil yang diharapkan). Namun, ketika saya menjalankannya dengan INNER JOIN, saya mendapatkan jumlah baris yang bervariasi - terkadang dua, kadang delapan.
Secara logis, seharusnya tidak ada perbedaan karena saya tahu baris dengan database_ids 1-4 ada di sys.databases. Dan karena kita memilih dari tabel angka acak dengan empat baris (sebagai lawan bergabung dengannya), seharusnya tidak pernah ada lebih dari empat baris yang dikembalikan.
Ini terjadi di SQL Server 2012 dan 2014. Apa yang menyebabkan INNER JOIN untuk mengembalikan jumlah baris yang berbeda?
/* 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()) ;
Saya kira itu berfungsi dengan baik karena tidak ada gabungan pada nilai fungsi non-deterministik.