我正在解决这个问题:How can I randomly do a partial outer join in SQL最后没有用,因为可以多次分配同一行。
但是我有一个行为我无法解释查询在哪里没有返回预期的行数
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
tableA
5行,tableB
15行。 tableA中每行有3个随机tableB
行。所以总共应该返回3 * 5 = 15行row_number()
以匹配幻数创建random_id
cte,为tableA的每一行分配三个随机数。在这里,您可以看到带有随机数的15行,同时在分配相同值时显示问题
SELECT * FROM random_id;
但是JOIN
会返回一个随机数。多于少于15
SELECT R.*, note
FROM random_id R
JOIN tableB
ON R.magic_number = tableB.rn
ORDER BY id
但如果我使用LEFT JOIN
而是总是返回15行。
问题:如果random_id
cte始终返回15行JOIN
返回更多行的方式,以及如果所有rn
值都在tableB中则返回的方式更少。
LEFT JOIN
总是如何返回15行。
我只测试另一个查询,其中包含n
值和JOIN
答案 0 :(得分:1)
不幸的是,您必须将使用magic_number
的行保留到临时表或其他类似的构造中。
rextester演示:http://rextester.com/ICS74177
不幸的是,将它保存到临时表会导致您尝试的答案失去优雅。我曾经遇到同样的情况,试图做同样的事情并遇到同样的错误。当你第一次碰到它时,它有点令人兴奋并最终令人失望,所以至少恭喜你!
我无法更好地解释,所以请在这里赞成保罗怀特的回答:https://dba.stackexchange.com/a/30348/43889
参考: