SQL 通过显示具有空值的所有列和行来显示带有组的服务器视图

SQL Server view with group by displaying all columns and rows with null values

我在 SQL Server 2017 中有一个 table 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    |  
+-----------+----------+--------+----------+----------+-------+  

我正在尝试创建一个视图,其中 returns 行按 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], [rule_set], [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有两点不符合我的要求:

+-----------+----------+--------+----------+----------+-------+  
| 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;