【问题标题】:Extract the max date values for 4 different items from a list of thousands从数千个列表中提取 4 个不同项目的最大日期值
【发布时间】:2026-02-20 11:05:01
【问题描述】:

我有一个查询如下

SELECT *
  FROM [VNPoller].[DBA].[uccpu1mUTMStats]
    WHERE resid in (SELECT resid
            FROM [VNPoller].[DBA].[ResourceView]
            WHERE Dataset in 
                (SELECT dataset     
                FROM [VNPoller].[DBA].[DatasetTable]
                WHERE datasetDescription LIKE '%CPU%'
                 )
             AND devID = '1157') 
    order by dttm desc

我有一个每 5 分钟轮询一次的设备列表,每次轮询都会在表中添加一个具有最新值的新行,在这种情况下,我正在查看 CPU。但是,一个设备可能有多个 CPU,所以在过去的 5 分钟内我可能有 4 个 CPU 值,因此数据库中有 4 个新条目。每个 CPU 都有一个唯一的 resID。我需要查看 4 个驻留中每个驻留的 Max(最新 dttm 值。我的查询返回一整天的所有行。或者我可以得到是使用 max(dttm) 仅显示一个值,但我需要其他 3 个价值观。也许一张图片可以帮助解释。非常感谢任何可以在这里提供帮助的人

我只对查看前 4 个项目感兴趣(每个不同驻留的最大 (dttm)。其余的都是重复的,但用于早期时间戳

来自uccpu1mUTMStats 表的样本数据,实际上包含数千行:

dttm                    resID   cpmCPUTotalMonIntervalValue
2018-09-28 22:10:00.000 294324  0
2018-09-28 22:10:00.000 294325  0
2018-09-28 22:10:00.000 294432  1
2018-09-28 22:10:00.000 294482  0
2018-09-28 22:10:01.000 294415  0
2018-09-28 22:10:01.000 294433  1
2018-09-28 22:10:01.000 294669  0
2018-09-28 22:10:02.000 294396  0
2018-09-28 22:10:02.000 294397  0
2018-09-28 22:10:02.000 294416  0
2018-09-28 22:10:03.000 294417  0
2018-09-28 22:10:03.000 294434  1
2018-09-28 22:10:03.000 294435  1
2018-09-28 22:10:04.000 294398  0
2018-09-28 22:10:04.000 294399  0
2018-09-28 22:10:04.000 294418  0
2018-09-28 22:10:05.000 294400  0
2018-09-28 22:10:05.000 294419  0

预期结果是:

dttm                    resID   cpmCPUTotalMonIntervalValue
2018-10-05 15:21:37.000 294100  21
2018-10-05 15:21:24.000 294099  23
2018-10-05 15:20:53.000 294098  19
2018-10-05 15:20:16.000 294097  23

【问题讨论】:

标签: sql sql-server max


【解决方案1】:

这使用RANK() 函数将结果按resID 划分,按时间排序。 TOP 1 WITH TIES 将结果集限制为仅最新的值。

SELECT TOP 1 WITH TIES
  *
  FROM [VNPoller].[DBA].[uccpu1mUTMStats]
    WHERE resid in (SELECT resid
            FROM [VNPoller].[DBA].[ResourceView]
            WHERE Dataset in 
                (SELECT dataset     
                FROM [VNPoller].[DBA].[DatasetTable]
                WHERE datasetDescription LIKE '%CPU%'
                 )
             AND devID = '1157') 
    ORDER BY RANK() OVER (PARTITION BY resID ORDER BY dttm DESC)

【讨论】:

  • 埃里克,你是怎么做到的?它完美地工作。从来不知道 RANK 函数。我会做一些阅读以更好地理解它,但它正是我所需要的。我可能需要删除一些列,而不是使用 * 我可能会选择特定的列。生病试一试。谢谢
  • 它是ROW_NUMBER()RANK()DENSE_RANK() 系列窗口(ing)函数之一。还有LEADLAG,以及OVER() 子句的许多有趣应用。谷歌搜索快乐!很高兴它有帮助。
【解决方案2】:

分成两个查询更容易阅读:

最大id查询:

SELECT resid, MAX(dttm)
FROM [VNPoller].[DBA].[uccpu1mUTMstats] s
GROUP BY s.resid

现在您可以将此查询加入到另一个查询中

SELECT *
FROM [VNPoller].[DBA].[uccpu1mUTMStats] AS r
JOIN (SELECT resid AS resid, MAX(dttm) as dttm
         FROM [VNPoller].[DBA].[uccpu1mUTMstats] s
         GROUP BY s.resid) AS sq ON sq.dttm = r.dttm
WHERE r.resid in (SELECT resid
        FROM [VNPoller].[DBA].[ResourceView]
        WHERE Dataset in 
            (SELECT dataset     
            FROM [VNPoller].[DBA].[DatasetTable]
            WHERE datasetDescription LIKE '%CPU%'
             )
         AND devID = '1157') 

【讨论】:

  • 嗨 Isitar 只是试试这个看看它是否有效。我应该如何最好地将这两个查询结合在一起?
  • 啊,是的,我现在看到了。唯一的问题是我需要选择的 dttm 值来自 uccpu1mUTMstats 表,而不是 resourceView。
  • 最上面的部分首先工作 - 我看到在线错误的蔑视部分
  • GROUP BY s.resid) AS sq ON sq.dttm = r.dttm (sp 没有指定列并且 dttm 是无效的列名。任何想法>
  • 差不多了,但我现在有 11 行而不是 4 行,第一个 resID 列显示重复,第二个 resID 列有一些我没想到的新驻留。我会仔细检查数据库表以确保。