SQL 服务器:如何按值分组,多列 n 天
SQL Server : how to group by value, multiple columns for n days
我找不到解决这个问题的方法,而且我的 SQL 技能很差,所以如果可以的话,也许有人可以提供建议。
环境:Microsoft SQL Server 2008 R2
当前的查询很简单,选择错误码的值,统计错误的个数,对错误码进行分组:
- EC - ErrorCode(大约有 200 种不同的错误代码)
- NoEr - count(*) as NoEr(有时错误计数可能为空)
查询:
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
输出:
+----+-------+
| EC | NoEr |
+----+-------+
| A9 | 3333 |
| E0 | 1505 |
| G9 | 1233 |
| X1 | 2 |
+----+-------+
我想获取最近 5 天的错误计数,如下所示:
+----+-------+-------+-------+-------+-------+
| EC | MON | TUE | WED | THU | FRI |
+----+-------+-------+-------+-------+-------+
| A9 | 1505 | 2333 | | 1555 | 9999 |
| E0 | 3333 | | 2311 | 5555 | 14 |
| G9 | 2222 | 1505 | 123 | 1233 | |
| X1 | 1212 | 1233 | 1155 | 3 | |
+----+-------+-------+-------+-------+-------+
谢谢你,祝你新年快乐!
您可以使用数据透视运算符来实现您的目标。
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
此致,
会
您可以使用 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
就像 Will 他说最好的选择是使用 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
你想要过去五天的结果,而不是一天的结果,所以我想你想要:
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
是指 "week" 还是 "weekday" 或者 m
是指 "minute" 还是 "month"。使用全名,避免歧义。
如果您愿意,还可以将其简化为:
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;
我找不到解决这个问题的方法,而且我的 SQL 技能很差,所以如果可以的话,也许有人可以提供建议。
环境:Microsoft SQL Server 2008 R2
当前的查询很简单,选择错误码的值,统计错误的个数,对错误码进行分组:
- EC - ErrorCode(大约有 200 种不同的错误代码)
- NoEr - count(*) as NoEr(有时错误计数可能为空)
查询:
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
输出:
+----+-------+
| EC | NoEr |
+----+-------+
| A9 | 3333 |
| E0 | 1505 |
| G9 | 1233 |
| X1 | 2 |
+----+-------+
我想获取最近 5 天的错误计数,如下所示:
+----+-------+-------+-------+-------+-------+
| EC | MON | TUE | WED | THU | FRI |
+----+-------+-------+-------+-------+-------+
| A9 | 1505 | 2333 | | 1555 | 9999 |
| E0 | 3333 | | 2311 | 5555 | 14 |
| G9 | 2222 | 1505 | 123 | 1233 | |
| X1 | 1212 | 1233 | 1155 | 3 | |
+----+-------+-------+-------+-------+-------+
谢谢你,祝你新年快乐!
您可以使用数据透视运算符来实现您的目标。
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
此致,
会
您可以使用 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
就像 Will 他说最好的选择是使用 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
你想要过去五天的结果,而不是一天的结果,所以我想你想要:
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
是指 "week" 还是 "weekday" 或者 m
是指 "minute" 还是 "month"。使用全名,避免歧义。
如果您愿意,还可以将其简化为:
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;