通过显示具有空值的所有列和行来显示具有组的SQL Server视图

问题描述

我在sql Server 2017中有一个Table,如下所示。 start是整数。其他所有列均为NVARCHAR(255)。

+-----------+----------+--------+----------+----------+-------+  
| operation | rule_set |  stem  | category | pattern  | start |  
+-----------+----------+--------+----------+----------+-------+  
| op1       | set1     | stem1  | cat1     | pattern1 | 100   |  
| op1       | set1     | stem1  | cat1     | pattern2 | 100   |  
| op1       | set1     | stem1  | cat2     | pattern3 | 150   |  
| op1       | set1     | stem2  | cat3     | pattern2 | 75    |  
| op1       | NULL     | stem3  | NULL     | NULL     | NULL  |  
| op1       | set2     | stem1  | cat5     | pattern3 | 85    |  
| op1       | set2     | stem3  | cat2     | pattern4 | 46    |  
+-----------+----------+--------+----------+----------+-------+  

我正在尝试创建一个视图,该视图返回按operationstem分组并且行的起始值最低的行,并返回具有该起始值的行的类别和模式。对于上面的前两行具有相同起始值的情况,我不在乎返回哪一行。结果还必须包括与第五行相同的任何具有空值的行。每个规则集都有一个单独的视图。

因此规则集set1的期望结果

+-----------+----------+--------+----------+----------+-------+  
| operation | rule_set |  stem  | category | pattern  | start |  
+-----------+----------+--------+----------+----------+-------+  
| op1       | set1     | stem1  | cat1     | pattern1 | 100   |  
| op1       | set1     | stem2  | cat3     | pattern2 | 75    |  
| op1       | NULL     | stem3  | NULL     | NULL     | NULL  |  
+-----------+----------+--------+----------+----------+-------+  

到目前为止,我得到的最接近的是以下sql

SELECT [dbo].[Table].[operation],[dbo].[Table].[rule_set],[dbo].[Table].[stem],[dbo].[Table].[category],[dbo].[Table].[pattern],[dbo].[Table].[start]
FROM
    (
    SELECT
        [operation],[rule_set],[stem],MIN(start) AS first
    FROM [dbo].[Table]
    WHERE [dbo].[Table].[rule_set] = 'set1'
    GROUP BY [operation],[stem]
    ) temp
INNER JOIN [dbo].[Table]
ON
    [temp].[operation] = [dbo].[Table].[operation] AND
    [temp].[rule_set] = [dbo].[Table].[rule_set] AND
    [temp].[stem] = [dbo].[Table].[stem] AND
    [temp].[first] = [dbo].[Table].[start]

但是上述sql在两个方面都不能满足我的要求:

  • 它为stem1返回两行(起始值为100),而它应该选择两行之一
  • 它不包含带有空值的行。
    也就是说,实际结果如下:
+-----------+----------+--------+----------+----------+-------+  
| operation | rule_set |  stem  | category | pattern  | start |  
+-----------+----------+--------+----------+----------+-------+  
| op1       | set1     | stem1  | cat1     | pattern1 | 100   |  
| op1       | set1     | stem1  | cat1     | pattern2 | 100   |  
| op1       | set1     | stem2  | cat3     | pattern2 | 75    |  
+-----------+----------+--------+----------+----------+-------+  

如何更改上面的sql代码以获得所需的结果?

解决方法

您要描述的是:

select t.*
from (select t.*,row_number() over (partition by rule_set,stem order by start) as seqnum
      from t
     ) t
where start is null or seqnum = 1;