SQL Server:如何按值分组多列,持续n天

时间:2018-12-31 08:19:28

标签: sql sql-server sql-server-2008

我找不到解决方案,而且我的SQL技能很差,所以也许有人可以建议以下情况。

环境:Microsoft SQL Server 2008 R2

当前查询非常简单,选择错误代码的值,计算错误数量并按错误代码分组:

  • EC-ErrorCode(有大约200个不同的错误代码)
  • NoEr-计数(*)为NoEr(有时错误计数可以为空)

查询:

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("document.getElementById('metal').value='4200';");

输出:

SELECT 
    ErrorCode AS EC, COUNT(*) as NoEr 
FROM 
    [DB].[dbo].[Table] 
WHERE
    ERRORTIME > '2018-12-30 00:00:00' 
    AND ERRORTIME < '2018-12-30 23:59:59' 
GROUP BY
    errorcode 
ORDER BY 
    ERRORCODE ASC

我希望获得如下显示的最近5天的错误计数:

+----+-------+
| EC |  NoEr |  
+----+-------+
| A9 |  3333 | 
| E0 |  1505 |
| G9 |  1233 | 
| X1 |  2    | 
+----+-------+

谢谢您,祝您新年快乐!

4 个答案:

答案 0 :(得分:1)

您可以将CASE表达式与汇总SUM一起计算出每个工作日的计数,如下所示-

Select 
    ErrorCode as EC,
    SUM(CASE WHEN Datename(w, ErrorTime) = 'Monday' THEN 1 ELSE 0 END) as MON,
    SUM(CASE WHEN Datename(w, ErrorTime) = 'Tuesday' THEN 1 ELSE 0 END) as TUE,
    SUM(CASE WHEN Datename(w, ErrorTime) = 'Wednesday' THEN 1 ELSE 0 END) as WED,
    SUM(CASE WHEN Datename(w, ErrorTime) = 'Thursday' THEN 1 ELSE 0 END) as THU,
    SUM(CASE WHEN Datename(w, ErrorTime) = 'Friday' THEN 1 ELSE 0 END) as FRI
From
    [DB].[dbo].[Table]
where 
    ERRORTIME > '2018-12-30 00:00:00' and ERRORTIME < '2018-12-30 23:59:59' 
group by errorcode 
order by ERRORCODE ASC

答案 1 :(得分:0)

您可以使用数据透视运算符实现目标。

SELECT 
EC,[MON],[TUE],[WED],[THU],[FRI]
FROM 
(
SELECT 
ErrorCode AS EC,UPPER(LEFT(DATENAME(DW,ERRORTIME),3)) AS D_W, 1 AS NUMBER FROM [DB].[dbo].[Table]
WHERE DATEDIFF(DAY,ERRORTIME,GETDATE())<=5
) SRC
PIVOT
(
SUM(NUMBER) FOR D_W IN ([MON],[TUE],[WED],[THU],[FRI])
) PVT

最好的问候,

答案 2 :(得分:0)

就像威尔说的那样,最好的选择是使用PIVOT:

SELECT 
    *
FROM
(
    SELECT 
        ErrorCode AS                               EC, 
        UPPER(LEFT(DATENAME(DW, ERRORTIME), 3)) AS DayW, 
        1 AS                                   Number
    FROM 
         table_name
    WHERE
                ERRORTIME > = DATEADD(day, -5, GetDate())
) AS Source PIVOT(SUM(Number) FOR DayW IN(
    [MON], 
    [TUE], 
    [WED], 
    [THU], 
    [FRI])) PVT

答案 3 :(得分:0)

您想要最近五天而不是一天的结果,所以我想您想要:

SELECT ErrorCode as EC,
       SUM(CASE WHEN datename(weekday, ErrorTime) = 'Monday' THEN 1 ELSE 0 END) as MON,
       SUM(CASE WHEN datename(weekday, ErrorTime) = 'Tuesday' THEN 1 ELSE 0 END) as TUE,
       SUM(CASE WHEN datename(weekday, ErrorTime) = 'Wednesday' THEN 1 ELSE 0 END) as WED,
       SUM(CASE WHEN datename(weekday, ErrorTime) = 'Thursday' THEN 1 ELSE 0 END) as THU,
       SUM(CASE WHEN datename(weekday, ErrorTime) = 'Friday' THEN 1 ELSE 0 END) as FRI
FROM [DB].[dbo].[Table] t
WHERE ERROR_TIME >= DATEADD(DAY, -5, CAST(GETDATE() as DATE)) AND
      ERROR_TIME >= CAST(GETDATE() as DATE)
GROUP BY errorcode 
ORDER BY ERRORCODE ASC;

请注意,当您使用诸如DATEADD()DATENAME()之类的功能时,应使用缩写。那只是一个不良的查询编写习惯。没有人想记住w是“星期”还是“工作日”,或者m是“分钟”还是“月”。使用全名并避免歧义。

如果您愿意,还可以简化为:

SELECT ErrorCode as EC,
       SUM(CASE WHEN ErrorTime_weekday = 'Monday' THEN 1 ELSE 0 END) as MON,
       SUM(CASE WHEN ErrorTime_weekday = 'Tuesday' THEN 1 ELSE 0 END) as TUE,
       SUM(CASE WHEN ErrorTime_weekday = 'Wednesday' THEN 1 ELSE 0 END) as WED,
       SUM(CASE WHEN ErrorTime_weekday = 'Thursday' THEN 1 ELSE 0 END) as THU,
       SUM(CASE WHEN ErrorTime_weekday = 'Friday' THEN 1 ELSE 0 END) as FRI
FROM [DB].[dbo].[Table] t CROSS APPLY
     (VALUES (datename(weekday, ErrorTime) = 'Thursday' THEN 1 ELSE 0 END))
     ) v(ErrorTime_weekday)
WHERE ERROR_TIME >= DATEADD(DAY, -5, CAST(GETDATE() as DATE)) AND
      ERROR_TIME >= CAST(GETDATE() as DATE)
GROUP BY errorcode 
ORDER BY ERRORCODE ASC;