2017-05-16 60 views
1

我正在解決這個問題:How can I randomly do a partial outer join in SQL最後沒有工作,因爲可以多次分配同一行。SQL加入不匹配所有元素

但是我有一個問題我無法解釋該查詢不返回預期的行數

SQL DEMO

WITH tableA as (
    SELECT T.id 
    FROM (VALUES (111), (222), (333), (444), (555)) T(id) 
), tableB as (
    SELECT *, row_number() over (order by note) as rn 
    FROM (VALUES ('a'), ('b'), ('c'), ('d'), ('e'), 
        ('f'), ('g'), ('h'), ('i'), ('j'), 
        ('k'), ('l'), ('m'), ('n'), ('o') 
     ) T(note) 
), parameter as (
    SELECT 3 as row_limit, (SELECT MAX(rn) FROM tableB) as max_limit 
), Nums AS (
    SELECT n = ROW_NUMBER() OVER (ORDER BY [object_id]) 
    FROM sys.all_objects 
), random_id as (
    SELECT tableA.*, T.n, floor(p.max_limit * RAND(convert(varbinary, newid()))) + 1 magic_number 
    FROM tableA 
    CROSS JOIN parameter p 
    CROSS JOIN (SELECT n 
       FROM Nums 
       CROSS JOIN parameter p 
       WHERE n <= p.row_limit) T 
) 
-- SELECT * FROM random_id 
SELECT R.*, note 
FROM random_id R 
JOIN tableB 
    ON R.magic_number = tableB.rn 
ORDER BY id  
  1. 的設置:tableA 5行,tableB 15排。 3個隨機tableB行爲tableA中的每一行。因此,在總應該返回3 * 5 = 15行
  2. 我從1到15創建row_number()匹配到一個神奇的數字
  3. 創建random_id CTE來assing三個隨機數表A的每一行。在這裏,你可以看到15排,一個隨機數,分配時相同的值的兩倍

    SELECT * FROM random_id; 
    

    [1]: https://i.stack.imgur.com/awX6

  4. JOIN返回行的隨機數也顯示問題。以上至小於15

    SELECT R.*, note 
    FROM random_id R 
    JOIN tableB 
        ON R.magic_number = tableB.rn 
    ORDER BY id    
    

    enter image description here

  5. 但是,如果使用LEFT JOIN而不是總是返回15行。

問題:如果random_id CTE總是返回15行如何JOIN返回更多的行,以及如何返回更少,如果所有rn值在tableB的。

而且LEFT JOIN總是返回15行。

我只是測試的另一個查詢,我包括n值和JOIN

+2

[ b uid與newid()和表表達式(ctes)](https://connect.microsoft.com/SQLServer/feedbackdetail/view/350485/bug-with-newid-and-table-expressions) – SqlZim

+1

以下是類似的情況Paul White的一個很好的解釋是:https://dba.stackexchange.com/a/30348/43889 – SqlZim

回答

1

不幸的是,你必須堅持正在使用magic_number到臨時表或其它類似結構的行。

rextester演示在這裏:http://rextester.com/ICS74177

不幸的是堅持到一個臨時表並導致你試圖回答的優雅的損失。在過去,我遇到了同樣的情況,試圖做同樣的事情,並遇到同樣的錯誤。當你第一次遇到它時,這有點令人興奮並且最終令人失望,所以至少恭喜你!

我無法解釋它更好,所以請給予好評保羅·懷特的回答這裏:https://dba.stackexchange.com/a/30348/43889

參考:

+0

你看起來和我的bug非常相似,怪異的部分是'LEFT JOIN'似乎是一個工作:/ –

相關問題