首页 > 解决方案 > SQL:使用多个条件选择每个名称的单个项目

问题描述

我试图根据几个标准在“名称”列中为每个值选择一个项目。

我想使用的标准如下所示:

  1. 仅包括 IsEnabled = 1 的结果
  2. 返回具有最低优先级的单个结果(我们使用 1 表示“最高优先级”)
  3. 如果出现平局,则返回带有最新时间戳的结果

我已经看到了其他几个关于返回给定值的最新时间戳的问题,并且我已经能够对其进行调整以返回优先级的最小值 - 但我不知道如何过滤掉两个优先级和时间戳。

这是对我到目前为止最有帮助的问题。

样本数据:

+------+------------+-----------+----------+
| Name |  Timestamp | IsEnabled | Priority |
+------+------------+-----------+----------+
|  A   | 2018-01-01 |     1     |    1     |
|  A   | 2018-03-01 |     1     |    5     |
|  B   | 2018-01-01 |     1     |    1     |
|  B   | 2018-03-01 |     0     |    1     |
|  C   | 2018-01-01 |     1     |    1     |
|  C   | 2018-03-01 |     1     |    1     |
|  C   | 2018-05-01 |     0     |    1     |
|  C   | 2018-06-01 |     1     |    5     |
+------+------------+-----------+----------+

期望的输出:

+------+------------+-----------+----------+
| Name |  Timestamp | IsEnabled | Priority |
+------+------------+-----------+----------+
|  A   | 2018-01-01 |     1     |    1     |
|  B   | 2018-01-01 |     1     |    1     |
|  C   | 2018-03-01 |     1     |    1     |
+------+------------+-----------+----------+

到目前为止我尝试过的(这让我只启用了优先级最低的项目,但不会过滤最新的项目以防出现平局):

SELECT DATA.Name, DATA.Timestamp, DATA.IsEnabled, DATA.Priority
From MyData AS DATA
INNER JOIN (
  SELECT MIN(Priority) Priority, Name
  FROM MyData
  GROUP BY Name
) AS Temp ON DATA.Name = Temp.Name AND DATA.Priority = TEMP.Priority
WHERE IsEnabled=1

这也是一个 SQL 小提琴。

如何增强此查询以仅返回现有过滤器之外的最新结果?

标签: sqlsql-server

解决方案


使用row_number()

select d.*
from (select d.*,
             row_number() over (partition by name order by priority, timestamp) as seqnum
      from mydata d
      where isenabled = 1
     ) d
where seqnum = 1;

推荐阅读