问题描述
我在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 |
+-----------+----------+--------+----------+----------+-------+
我正在尝试创建一个视图,该视图返回按operation
和stem
分组并且行的起始值最低的行,并返回具有该起始值的行的类别和模式。对于上面的前两行具有相同起始值的情况,我不在乎返回哪一行。结果还必须包括与第五行相同的任何具有空值的行。每个规则集都有一个单独的视图。
因此规则集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 |
+-----------+----------+--------+----------+----------+-------+
解决方法
您要描述的是:
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;