У мене простий скрипт, який отримує чотири випадкових числа (від 1 до 4), а потім приєднується назад, щоб отримати відповідне число баз даних_id. Коли я запускаю сценарій з НАЛЯГОЮ ПРИЄДНАЙТЕСЯ, я отримую чотири ряди назад кожен раз (очікуваний результат). Однак, коли я запускаю її за допомогою ВНУТРІШНОГО ПРИЄДНАННЯ, я отримую різну кількість рядків - іноді два, іноді вісім.
За логікою, різниці не повинно бути, тому що я знаю, що рядки з database_ids 1-4 існують у sys.databases. А оскільки ми вибираємо з таблиці випадкових чисел чотири рядки (на відміну від приєднання до неї), ніколи не повинно бути повернуто більше чотирьох рядків.
Це відбувається як в SQL Server 2012, так і в 2014 р. Що змушує INNER JOIN повертати різну кількість рядків?
/* 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()) ;
я думаю, це працює добре, оскільки немає значення приєднання значення недетермінованої функції.