过滤掉 SQL Query 中的重复行

Posted

技术标签:

【中文标题】过滤掉 SQL Query 中的重复行【英文标题】:Filter out duplicate rows in SQL Query 【发布时间】:2020-03-29 01:40:14 【问题描述】:

我正在尝试使用 SQL 从 SCCM 提取更新合规性数据,并提出了以下查询:

SELECT updates.ArticleID, updates.Title, devices.Name, MAX(compliance.LastStatusChangeTime) AS LastUpdated, compliance.[Status]
FROM v_UpdateDeploymentSummary deployments
INNER JOIN v_UpdateInfo updates
    ON deployments.CI_ID=updates.CI_ID
INNER JOIN CollectionMembers devices
    ON deployments.CollectionID=devices.SiteID
INNER JOIN v_UpdateComplianceStatus compliance
    ON compliance.CI_ID=deployments.CI_ID
WHERE compliance.[Status] IS NOT NULL
GROUP BY updates.ArticleID, updates.Title, devices.Name, compliance.[Status]
ORDER BY ArticleID, LastUpdated DESC

但是,SCCM 似乎为同一个更新部署存储了多个合规性状态记录。例如,昨晚在该设备上安装了 KB890830,从今天早上 09:19 开始,这反映在下面的行中。我想更改查询,以便返回的唯一行是第 15 行,显示该 KB 的最新状态更新。

有什么建议吗?

【问题讨论】:

【参考方案1】:

您可以使用窗口函数row_number() 进行过滤,而不是聚合:

SELECT *
FROM (
    SELECT 
        updates.ArticleID, 
        updates.Title, 
        devices.Name, 
        compliance.LastStatusChangeTime AS LastUpdated, 
        compliance.[Status],
        ROW_NUMBER() OVER(
            PARTITION BY updates.ArticleID 
            ORDER BY compliance.LastStatusChangeTime DESC
        ) rn
    FROM v_UpdateDeploymentSummary deployments
    INNER JOIN v_UpdateInfo updates
        ON deployments.CI_ID=updates.CI_ID
    INNER JOIN CollectionMembers devices
        ON deployments.CollectionID=devices.SiteID
    INNER JOIN v_UpdateComplianceStatus compliance
        ON compliance.CI_ID=deployments.CI_ID
    WHERE compliance.[Status] IS NOT NULL
) t
WHERE rn = 1
ORDER BY ArticleID, LastUpdated DESC

在内部查询中,row_number() 将排名分配给具有相同ArticleID 的记录,按降序排列LastStatusChangeTime。然后,外部查询过滤每个组中的顶部记录。

【讨论】:

以上是关于过滤掉 SQL Query 中的重复行的主要内容,如果未能解决你的问题,请参考以下文章

SQL SERVER怎么去掉重复数据?

使用特定于列的重复过滤器在 Python 中将行附加到 CSV

在运行时过滤掉 SQL 数据库中的重复值 - 基于集合

突出显示类似于 grep 的文本,但不过滤掉文本 [重复]

MySQL根据列中的最大值获取行[重复]

BigQuery:使用标准 SQL 过滤重复字段