SQL补丁合规查询结果异常:多行状态问题排查求助
补丁合规状态SQL查询问题分析
首先看你的需求:想要每个补丁(按ArticleID和Title)一行汇总出「No Status」「In Progress」「Failed」「Success」这几个状态的主机数量,但实际输出却是每个状态单独一行,这是因为你的查询在两个核心逻辑上出了问题:
错误点解析
- 分组逻辑错误:你的
GROUP BY里包含了vsn.StateID,这会让SQL把每个不同的状态ID单独分成一组,自然每个状态就会生成一行记录,而不是把同一个补丁的所有状态汇总到一行。 - 聚合函数用法错误:你把
COUNT()放在了CASE表达式内部,这只会统计当前分组(也就是当前StateID组)的数量,而不是跨分组汇总符合条件的记录数。正确的做法应该是用SUM()包裹CASE表达式,判断每条记录是否符合某个状态,符合的话计为1,最后求和得到该状态的总数量。
另外还要注意一个细节:你的CASE条件里StateID=14同时出现在「In Progress」和「Failed」两个分支里,这会导致同一台主机被重复统计,你需要先确认这个状态ID对应的实际含义,调整条件避免重复。
修正后的SQL查询
SELECT vUI.Title AS 'Title', vui.ArticleID, SUM(CASE WHEN vsn.StateID IN (0,1,2) THEN 1 ELSE 0 END) AS 'No Status', SUM(CASE WHEN vsn.StateID IN (3,4,5,7,8,12) THEN 1 ELSE 0 END) AS 'In Progress', -- 移除了重复的14 SUM(CASE WHEN vsn.StateID IN (6,11,14) THEN 1 ELSE 0 END) AS 'Failed', SUM(CASE WHEN vsn.StateID IN (9,10) THEN 1 ELSE 0 END) AS 'Success' FROM v_UpdateComplianceStatus vUCS JOIN v_UpdateInfo vUI ON vUCS.CI_ID = vUI.CI_ID JOIN v_R_System_Valid vRSV ON vUCS.ResourceId = vRSV.resourceid INNER JOIN v_FullCollectionMembership_Valid vFCMV ON vUCS.ResourceId = vFCMV.ResourceID AND vFCMV.CollectionID='CB00123' JOIN v_GS_OPERATING_SYSTEM vGOS ON vUCS.ResourceID = vGOS.ResourceID JOIN v_StateNames vSN ON vUCS.LastEnforcementMessageID = vSN.StateID AND (vSN.TopicType=402 OR vSN.TopicType=500 OR vSN.TopicType=400) WHERE vui.DateLastModified BETWEEN '2019-09-12' AND '2019-10-12' GROUP BY vUI.Title, vui.ArticleID -- 移除了vsn.StateID
修正说明
- 移除了
GROUP BY中的vsn.StateID,现在只会按补丁的Title和ArticleID分组,每个补丁只会生成一行记录。 - 用
SUM(CASE ...)替代了原来的CASE ... COUNT(),每条符合状态条件的记录会被计为1,最终求和得到该状态的总主机数。 - 调整了「In Progress」的条件,移除了重复的
StateID=14,如果你确认14确实属于「In Progress」,就把它移回这个分支,确保每个StateID只属于一个状态列。
这样修正后,查询就能输出你预期的一行汇总格式了。
内容的提问来源于stack exchange,提问作者Roxx
相关产品推荐
相关产品推荐

