mardi 8 mars 2022

INNER JOIN involving RAND(...NEWID()) returns unexpected number of rows

I want to generate some sample data with random values.

I have a mini table with 5 rows, ids from 1 to 5 with some text for every row.

Then I want to generate 65536 rows - first column has value 1 for every row, second column is random number between 1 and 5, without NULL values.

Then I want to join these two tables. With ROW_NUMBER() % 5 approach INNER/OUTER JOIN returns 65536 rows.

Instead of this pseudo random column I want to use RAND seeded by NEWID.

LEFT JOIN returns 65536 rows as I suspected, but INNER JOIN returns different row count for every call.

When LFINAL table is materialized into temp table, then INNER JOIN works and returns 65536 rows too.

Can somebody explain to me why INNER JOIN does not return 65536 rows as I expected?

WITH Names AS 
(
    SELECT id, row_name 
    FROM 
        (SELECT 1, 'Row 1' UNION ALL 
         SELECT 2, 'Row 2' UNION ALL
         SELECT 3, 'Row 3' UNION ALL
         SELECT 4, 'Row 4' UNION ALL
         SELECT 5, 'Row 5') AS D (id, row_name)
),
L0 AS 
(
    SELECT c 
    FROM 
        (SELECT 1 UNION ALL SELECT 1) AS D(c)
),  --2^1
L1 AS 
(
    SELECT 1 AS c 
    FROM L0 AS A 
    CROSS JOIN L0 AS B
),          --2^2
L2 AS 
(
    SELECT 1 AS c 
    FROM L1 AS A 
    CROSS JOIN L1 AS B
),          --2^4
L3 AS 
(
    SELECT 1 AS c 
    FROM L2 AS A 
    CROSS JOIN L2 AS B
),          --2^8
L4 AS 
(
    SELECT 1 AS c 
    FROM L3 AS A 
    CROSS JOIN L3 AS B
),          --2^16 = 65536
LFINAL AS 
(
    SELECT 
        c, 
        --ROW_NUMBER() OVER (ORDER BY c) % 5 + 1 AS rnd FROM L4)
        FLOOR(RAND(CONVERT(VARBINARY, NEWID()))*5) + 1 AS rnd 
    FROM 
        L4
)
SELECT * 
FROM LFINAL lf
LEFT JOIN Names n ON n.id = lf.rnd



Aucun commentaire:

Enregistrer un commentaire