SQL Join与所有元素都不匹配

时间:2017-05-16 20:43:11

标签: sql sql-server join random

我正在解决这个问题:How can I randomly do a partial outer join in 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行。 tableA中每行有3个随机tableB行。所以总共应该返回3 * 5 = 15行
  2. 我从1到15创建一个row_number()以匹配幻数
  3. 创建random_id cte,为tableA的每一行分配三个随机数。在这里,您可以看到带有随机数的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行。

  6. 问题:如果random_id cte始终返回15行JOIN返回更多行的方式,以及如果所有rn值都在tableB中则返回的方式更少。

    LEFT JOIN总是如何返回15行。

    我只测试另一个查询,其中包含n值和JOIN

1 个答案:

答案 0 :(得分:1)

不幸的是,您必须将使用magic_number的行保留到临时表或其他类似的构造中。

rextester演示:http://rextester.com/ICS74177

不幸的是,将它保存到临时表会导致您尝试的答案失去优雅。我曾经遇到同样的情况,试图做同样的事情并遇到同样的错误。当你第一次碰到它时,它有点令人兴奋并最终令人失望,所以至少恭喜你!

我无法更好地解释,所以请在这里赞成保罗怀特的回答https://dba.stackexchange.com/a/30348/43889

参考: