【问题标题】:Filling missing rows , RIGHT JOIN with each group of GROUP BY填充缺失的行,与每组 GROUP BY 进行 RIGHT JOIN
【发布时间】:2018-04-29 23:21:18
【问题描述】:

在一张桌子上我有 Id,应该完成 10 个测试的名称。 在第二个 SN 产品上,对该产品进行了 TestDate 和 Id 测试。 我需要找到并显示应该完成的测试,但它们不是。

使用 CROSS JOIN 和 LEFT OUTER JOIN 的解决方案适用于 1000 行,但对于 8000-15000 则需要 1-3 分钟的时间。 数据由 CTE 查询准备

下面的例子 我想为每个组添加“缺失”行@Table2

@Table1 => four tests which should be done 
       number - Id of test
       data3  -name of test
@Table2 => tests which were done
       data1 - id of tested device
GROUP   => tests of one device

DECLARE @table1 TABLE (data3 NVARCHAR(20), number INT)
DECLARE @table2 TABLE (data1 NVARCHAR(20), data2 NVARCHAR(20), number INT)  

INSERT INTO @table1 
    SELECT 'xx', 1 
    UNION ALL 
    SELECT 'ee', 2 
    UNION ALL 
    SELECT 'zz', 3 
    UNION ALL 
    SELECT 'gg', 4

INSERT INTO @table2 
    SELECT '1', 'aaaaaaaaaa', 1 --GROUP 1
    UNION ALL 
    SELECT '1', 'aaaaaaaaaa', 2 --GROUP 1
    UNION ALL 
    SELECT '1', 'aaaaaaaaaa', 3 --GROUP 1
    UNION ALL 
    SELECT '2', 'bbbbbbbbbb', 1 --GROUP 2
    UNION ALL 
    SELECT '2', 'bbbbbbbbbb', 2 --GROUP 2
    UNION ALL 
    SELECT '3', 'cccccccccc', 1 --GROUP 3
    UNION ALL 
    SELECT '3', 'cccccccccc', 3 --GROUP 3

这个查询只添加了一行(第一行),我需要填充每组 table2

如果我的组是例如。按数据1,数据2分组

SELECT * 
FROM @table2 t2
RIGHT JOIN @table1 t1 ON t2.number = t1.number
ORDER BY t2.data1, t1.number

输出:

 data1  data2       number  data3   number
 -----------------------------------------
 NULL   NULL        NULL    gg      4
 1      aaaaaaaaaa  1       xx      1
 1      aaaaaaaaaa  2       ee      2
 1      aaaaaaaaaa  3       zz      3
 2      bbbbbbbbbb  1       xx      1
 2      bbbbbbbbbb  2       ee      2
 3      cccccccccc  3       zz      3
 3      cccccccccc  1       xx      1

这是我需要的输出(虽然只有一个“数字”列也可以)

 data1  data2       number  number3
 -----------------------------------------
 1      aaaaaaaaaa  1       1          --GROUP 1
 1      aaaaaaaaaa  2       2          --GROUP 1
 1      aaaaaaaaaa  3       3          --GROUP 1
 NULL   NULL        NULL    4          --GROUP 1
 2      bbbbbbbbbb  1       1          --GROUP 2
 2      bbbbbbbbbb  2       2          --GROUP 2
 NULL   NULL        NULL    3          --GROUP 2
 NULL   NULL        NULL    4          --GROUP 2
 3      cccccccccc  1       1          --GROUP 3
 NULL   NULL        NULL    2          --GROUP 3
 3      cccccccccc  3       3          --GROUP 3
 NULL   NULL        NULL    4          --GROUP 3

【问题讨论】:

  • 我想你有一个XY Problem。你能解释一下用例吗?
  • 很高兴您将示例数据发布为 DDL+DML、您当前的尝试和您想要的结果。但是,您的问题文本可能会更清楚。你应该想想你会向不做 SQL 的人解释这个问题,然后edit你的问题更清楚。

标签: sql-server tsql


【解决方案1】:

为什么您的data1 对于缺失 值是空的?我想它们必须从表 2 中填充。试试这个查询:

;with cte as (
    select
        distinct a.data1, b.number, b.data3
    from
        @table2 a
        cross join @table1 b
)

select
    c.data1, t.data2, t.number, c.data3, number3 = c.number
from
    cte c
    left join @table2 t on c.data1 = t.data1 and c.number = t.number

输出

data1   data2        number   data3   number3
---------------------------------------------
1       aaaaaaaaaa   1        xx      1
1       aaaaaaaaaa   2        ee      2
1       aaaaaaaaaa   3        zz      3
1       NULL         NULL     gg      4
2       bbbbbbbbbb   1        xx      1
2       bbbbbbbbbb   2        ee      2
2       NULL         NULL     zz      3
2       NULL         NULL     gg      4
3       cccccccccc   1        xx      1
3       NULL         NULL     ee      2
3       cccccccccc   3        zz      3
3       NULL         NULL     gg      4

如果你真的需要在data1列显示空值,那么添加case语句来检查data2的值。

【讨论】:

  • --“为什么你的 data1 对于缺失值是空的?” 'Table1' => 应该完成的四个测试 'Table2' => 已经完成的测试
  • @Artur,我猜你说的是numbernumber3 列。 Number - 已经完成的测试,number3 - 应该完成的测试。我相信data1 是组号不应该为空。但是,如果您真的希望它们为 null,只需在最后一次选择中将 c.data1 更改为 case when t.data2 is null then null else c.data1 end
  • 是的,你说得对。查询对于 table2 中的 1000 行工作正常,但对于 15000 行需要 60 秒 :(
  • 在一张桌子上我有 Id,应该完成 10 个测试的名称。在第二个 SN 产品上,对该产品进行了 TestDate 和 Id 测试。我需要找到并显示应该完成的测试,但它们不是。
  • 我不明白你的意思。此查询不会返回您的预期结果吗?如果您的问题是查询的性能,那完全是另一个问题。您应该问另一个提供完整表结构的问题。然后你可能会得到一些关于索引表的提示
猜你喜欢
  • 2015-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-31
  • 2018-06-06
相关资源
最近更新 更多