如何计算分组查询中的项目数并显示Top(x)?

时间:2019-04-04 20:13:11

标签: sql sql-server group-by count

我正在尝试按查询显示来自分组结果的最多错误

我认为我的初始组是正确的,但无法找出子查询来按模块对错误数进行计数并滤除最高计数。

SELECT Code AS Module
   , ErrCode As ErrorCode
   , Count(ErrCode) AS ErrorCount
   , CAST([Msg-EN] as varchar(max)) as ErrorMsg
FROM ViewAllAlarm
WHERE RiseTime >= DateAdd(Hour, -12, GetDate())
GROUP BY Code, ErrCode,  CAST([Msg-EN] as varchar(max))
Order by Module ASC

结果:

Module | ErrorCode | ErrorCount | ErrorMsg
-------+-----------+------------+---------
F108   | 194       |        127 | Error2
F108   | 358       |        209 | Error1
F109   | 129       |         11 | Error3
F110   | 129       |        200 | Error3
F110   | 358       |        300 | Error1
F111   | 358       |          2 | Error1
F111   | 129       |          5 | Error3
F112   | 129       |         12 | Error3
F113   | 358       |        200 | Error1
F114   | 194       |        300 | Error2

我现在需要按模块总计错误数量(ErrorCount),并显示计数最高的模块(前5名)。

这给出了F108的336个错误,F109的11个错误,F110的500个错误,等等。我想展示五个具有最高错误计数的模块,它们是F110(500),F108(336),F114(300), F113(200),F112(12)。不会显示模块F129(11)和F111(7)。

Module | ErrorCode | ErrorCount | ErrorMsg
-------+-----------+------------+---------
F108   | 194       |        127 | Error2
F108   | 358       |        209 | Error1
F110   | 129       |        200 | Error3
F110   | 358       |        300 | Error1
F112   | 129       |         12 | Error3
F113   | 358       |        200 | Error1
F114   | 194       |        300 | Error2

这是在MS 2016 SQL服务器上。

3 个答案:

答案 0 :(得分:1)

使用IN子句仅选择错误次数最多的五个模块。

WITH current AS
(
  SELECT *
  FROM viewallalarm
  WHERE risetime >= DATEADD(HOUR, -12, GETDATE())
)
SELECT
    code AS module
  , errcode As errorcode
  , COUNT(*) AS errorcount
  , MAX(CAST([Msg-EN] as VARCHAR(MAX))) AS errormsg
FROM current
WHERE module IN
(
  SELECT TOP(5) WITH TIES code
  FROM current
  GROUP BY code
  ORDER BY COUNT(*) DESC
)
GROUP BY code, errcode
ORDER BY module;

或使用窗口功能:

SELECT *
FROM
(
  SELECT TOP(5) WITH TIES *
  FROM
  (
    SELECT
        code AS module
      , errcode As errorcode
      , COUNT(*) AS errorcount
      , CAST([Msg-EN] as VARCHAR(MAX)) AS errormsg
      , SUM(COUNT(*)) OVER(PARTITION BY code) AS total
    FROM viewallalarm
    WHERE risetime >= DATEADD(HOUR, -12, GETDATE())
    GROUP BY code, errcode, CAST([Msg-EN] AS VARCHAR(MAX))
  ) summed
  ORDER BY DENSE_RANK() OVER (ORDER BY total DESC)
) top_five
ORDER BY module;

答案 1 :(得分:0)

嗯。如果只需要模块,则使用group bytop

SELECT TOP (5) Code AS Module, COUNT(*) as cnt
FROM ViewAllAlarm
WHERE RiseTime >= DateAdd(Hour, -12, GetDate())
GROUP BY Code
ORDER BY COUNT(*) DESC;

如果您也想要这些错误,则可以使用窗口函数来解决,但我认为简单的连接可能是最简单的:

select vaa.*
from ViewAllAlarm vaa join
     (SELECT TOP (5) Code, COUNT(*) as cnt
      FROM ViewAllAlarm
      WHERE RiseTime >= DateAdd(Hour, -12, GetDate())
      GROUP BY Code
      ORDER BY COUNT(*) DESC
     ) t5
     on t5.code = vaa.code;

答案 2 :(得分:0)

如果我的SQL则使用限制

select Code AS Module, count(*) as cnt
FROM ViewAllAlarm
WHERE RiseTime >= DateAdd(Hour, -12, GetDate())
GROUP BY Code
ORDER BY COUNT(*) DESC limit 5