Dört rasgele sayılar (1-4) alır ve sonra eşleşen database_id numarasını almak için geri katıldı basit bir komut dosyası var. Bir LEFT JOIN ile senaryoyu çalıştırdığımda, her seferinde dört satır alıyorum (beklenen sonuç). Ancak, bir INNER JOIN ile çalıştırdığımda, değişen sayıda satır alıyorum - bazen iki, bazen sekiz.
Mantıksal olarak, herhangi bir fark olmamalı çünkü sys.databases veritabanı_id 1-4 ile satır var biliyorum. Ve dört satırlı rastgele sayı tablosundan (ona katılmanın aksine) seçim yaptığımız için, asla dörtten fazla satır döndürülmemelidir.
Bu, hem SQL Server 2012 hem de 2014'te olur. INNER JOIN değişken sayıda satır döndürmek için ne neden olur?
/* 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()) ;
Sanırım iyi çalışıyor çünkü deterministik olmayan fonksiyonun değerinde bir birleşim yok.