声明:本篇文章的SQL语句为了体现作者的思路,并非最优,请根据实际需要进行优化。
在开发的过程中,我们常常会遇到类似这种按每半小时统计数量的需求:
CREATE TABLE [dbo].[PerHalfHour]([CallInTime] [smalldatetime] NULL, [Result] [int] NULL); INSERT [dbo].[PerHalfHour] ([CallInTime], [Result]) VALUES ('2014-01-01 08:20:00', 2); INSERT [dbo].[PerHalfHour] ([CallInTime], [Result]) VALUES ('2014-01-01 08:38:00', 2); INSERT [dbo].[PerHalfHour] ([CallInTime], [Result]) VALUES ('2014-01-01 08:43:00', 2); INSERT [dbo].[PerHalfHour] ([CallInTime], [Result]) VALUES ('2014-01-01 08:49:00', 2); INSERT [dbo].[PerHalfHour] ([CallInTime], [Result]) VALUES ('2014-01-01 09:07:00', 2); INSERT [dbo].[PerHalfHour] ([CallInTime], [Result]) VALUES ('2014-01-01 09:07:00', 1); INSERT [dbo].[PerHalfHour] ([CallInTime], [Result]) VALUES ('2014-01-01 09:10:00', 1); INSERT [dbo].[PerHalfHour] ([CallInTime], [Result]) VALUES ('2014-01-01 09:16:00', 1); INSERT [dbo].[PerHalfHour] ([CallInTime], [Result]) VALUES ('2014-01-01 09:41:00', 1); INSERT [dbo].[PerHalfHour] ([CallInTime], [Result]) VALUES ('2014-01-01 09:44:00', 1); INSERT [dbo].[PerHalfHour] ([CallInTime], [Result]) VALUES ('2014-01-01 09:52:00', 1);
只统计其中的一部分并不难:
SELECT CallInTime_Hour, CallInTime_Minute, Count(*) AS CallInTime_Count FROM (SELECT Datepart(HOUR, CallInTime) AS CallInTime_Hour, Datepart(MINUTE, CallInTime) / 30 * 30 AS CallInTime_Minute /*??SQL ??/??=?? ??????????*/ FROM [PerHalfHour] WHERE CallInTime >= '2014-01-01' AND CallInTime < '2014-01-02') t GROUP BY CallInTime_Hour, CallInTime_Minute ORDER BY CallInTime_Hour, CallInTime_Minute
统计结果为:
但是实际需求可能要求显示全部24小时的统计,这时我们只要加一张外联表就可以了:
CREATE TABLE [dbo].[Sequence_HalfHour]([sequence_time] [nvarchar](20) NULL,[sequence_hour] [int] NULL,[sequence_minute] [int] NOT NULL); INSERT [dbo].[Sequence_HalfHour] ([sequence_time], [sequence_hour], [sequence_minute]) VALUES (N'00:00:00~00:29:59', 0, 0); INSERT [dbo].[Sequence_HalfHour] ([sequence_time], [sequence_hour], [sequence_minute]) VALUES (N'00:30:00~00:59:59', 0, 30); INSERT [dbo].[Sequence_HalfHour] ([sequence_time], [sequence_hour], [sequence_minute]) VALUES (N'01:00:00~01:29:59', 1, 0); INSERT [dbo].[Sequence_HalfHour] ([sequence_time], [sequence_hour], [sequence_minute]) VALUES (N'01:30:00~01:59:59', 1, 30); ... INSERT [dbo].[Sequence_HalfHour] ([sequence_time], [sequence_hour], [sequence_minute]) VALUES (N'23:00:00~23:29:59', 23, 0); INSERT [dbo].[Sequence_HalfHour] ([sequence_time], [sequence_hour], [sequence_minute]) VALUES (N'23:30:00~23:59:59', 23, 30);
然后用这个外联表去Left Join上一个查询就OK:
SELECT t0.sequence_time AS ???, Isnull(CallInTime_Count, 0) AS ?? FROM sequence_halfhour t0 LEFT JOIN (SELECT CallInTime_Hour, CallInTime_Minute, Count(*) AS CallInTime_Count FROM (SELECT Datepart(HOUR, CallInTime) AS CallInTime_Hour, Datepart(MINUTE, CallInTime) / 30 * 30 AS CallInTime_Minute /*??SQL ??/??=?? ??????????*/ FROM [PerHalfHour] WHERE CallInTime >= '2014-01-01' AND CallInTime < '2014-01-02') t GROUP BY CallInTime_Hour, CallInTime_Minute) t1 ON t0.sequence_hour = t1.CallInTime_Hour AND t0.sequence_minute = t1.CallInTime_Minute
查看结果:
留个尾巴:
第一张表里有个Result字段,请用SQL语句输出以下表格:
Pingback: [????]??????SQL??????????????? | ITDOC