【问题标题】:SQL Join doesn't match all elementsSQL Join 不匹配所有元素
【发布时间】:2017-10-16 02:40:20
【问题描述】:

我正在解决这个问题: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 行。表 A 中每一行的 3 个随机 tableB 行。所以总共应该返回 3 * 5 = 15 行
  2. 我创建了一个从 1 到 15 的 row_number() 以匹配幻数
  3. 创建random_id cte 为tableA 的每一行分配三个随机数。在这里你可以看到15行有一个随机数,同样显示两次分配相同值时的问题

    SELECT * FROM random_id;
    

  4. JOIN 返回随机数的行。大于和小于 15

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

  5. 但是如果我使用LEFT JOIN 总是返回 15 行。

问题:如果random_id cte 总是返回 15 行,JOIN 如何返回更多行,以及如果所有 rn 值都在 tableB 中,如何返回更少。

以及LEFT JOIN 如何总是返回 15 行。

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

【问题讨论】:

标签: sql sql-server join random


【解决方案1】:

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

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

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

我无法更好地解释它,所以请在此处支持 Paul White 的回答https://dba.stackexchange.com/a/30348/43889

参考:

【讨论】:

  • 你的错误似乎与我的错误非常相似,奇怪的部分是LEFT JOIN 似乎可以解决:/
猜你喜欢
  • 1970-01-01
  • 2020-06-19
  • 1970-01-01
  • 2019-12-29
  • 2019-10-06
  • 2017-03-15
  • 2017-05-27
  • 1970-01-01
  • 2022-06-16
相关资源
最近更新 更多