如何获得前12周的2个不同聚合

时间:2014-09-29 17:06:30

标签: sql sql-server-2008 analytics

使用sql server 2008

我正在寻找一个单一的SQL解决方案。

现在我有两个查询,无法弄清楚如何将它转换为单个sql结果集。

如果可能的话,我不想使用临时表。

我希望计算过去12周内每周开启和关闭的所有通话和结束通话。 任何通话状态> 3表示已完成通话。

-- Create table with data
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--drop table calltable
--go
CREATE TABLE [dbo].[calltable](
    [PKID] [int] IDENTITY(1,1) NOT NULL,
    [incident_number] [int] NOT NULL,
    [call_date] [datetime] NOT NULL,
    [status] [int] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES (145, CAST(0x0000A36500F55347 AS DateTime), 9)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES (192, CAST(0x0000A3A200F5534C AS DateTime), 1)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES (105, CAST(0x0000A36800F5534C AS DateTime), 3)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES (732, CAST(0x0000A39C00F5534C AS DateTime), 9)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES (62, CAST(0x0000A35B00F5534C AS DateTime), 9)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES (188, CAST(0x0000A394010A48D0 AS DateTime), 7)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES (844, CAST(0x0000A380010A48F1 AS DateTime), 1)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES (77, CAST(0x0000A387010A48F1 AS DateTime), 8)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES (263, CAST(0x0000A352010A48F1 AS DateTime), 8)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 556, CAST(0x0000A394010A48F1 AS DateTime), 8)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 546, CAST(0x0000A37E010A5D8F AS DateTime), 3)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 17, CAST(0x0000A378010A5D8F AS DateTime), 5)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 652, CAST(0x0000A377010A5D94 AS DateTime), 7)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 107, CAST(0x0000A356010A5D94 AS DateTime), 9)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 96, CAST(0x0000A3A5010A5D94 AS DateTime), 7)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 668, CAST(0x0000A36D010A5E33 AS DateTime), 6)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 756, CAST(0x0000A37A010A5E33 AS DateTime), 3)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 286, CAST(0x0000A361010A5E33 AS DateTime), 1)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 591, CAST(0x0000A39D010A5E33 AS DateTime), 7)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 975, CAST(0x0000A37F010A5E33 AS DateTime), 3)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 788, CAST(0x0000A37C010A5F0B AS DateTime), 9)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 892, CAST(0x0000A390010A5F10 AS DateTime), 9)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 51, CAST(0x0000A38C010A5F14 AS DateTime), 10)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 302, CAST(0x0000A356010A5F14 AS DateTime), 0)
INSERT [dbo].[calltable] ([incident_number], [call_date], [status]) VALUES ( 717, CAST(0x0000A374010A5F14 AS DateTime), 6)



-- Queries
DECLARE @WeeksBack SMALLINT
DECLARE @ReportEndDate DATETIME

SET @ReportEndDate = '2014-09-27'
SET @WeeksBack = 12

SELECT ct.call_date
   , DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + (CAST(DATEPART(YY, ct.call_date) AS CHAR(4)))) + ((DATEPART(WK, ct.call_date)) - 1), 6) AS reportstartdate
   , DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + (CAST(DATEPART(YY, ct.call_date) AS CHAR(4)))) + ((DATEPART(WK, ct.call_date)) - 1), 5) AS reportenddate
   , count(*) OVER (PARTITION BY datepart(week, ct.call_date)) AS OpenedCallCt
   , NULL
FROM calltable ct
WHERE ct.call_date <= @ReportEndDate
   AND ct.call_date >= dateadd(day, (- 7 * @WeeksBack), @ReportEndDate)

SELECT ct.call_date
   , DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + (CAST(DATEPART(YY, ct.call_date) AS CHAR(4)))) + ((DATEPART(WK, ct.call_date)) - 1), 6) AS reportstartdate
   , DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + (CAST(DATEPART(YY, ct.call_date) AS CHAR(4)))) + ((DATEPART(WK, ct.call_date)) - 1), 5) AS reportenddate
   , count(*) OVER (PARTITION BY datepart(week, ct.call_date)) AS ClosedCallCt
   , NULL
FROM calltable ct
WHERE ct.call_date <= @ReportEndDate
   AND ct.call_date >= dateadd(day, (- 7 * @WeeksBack), @ReportEndDate)
   and ct.STATUS > 3

Query1 Resultset(partial):

 reportstartdate           reportenddate             OpenedCallCt
------------------------- ------------------------- --------------
 2014-07-06 00:00:00.000   2014-07-12 00:00:00.000    2
 2014-07-06 00:00:00.000   2014-07-12 00:00:00.000    2
 2014-07-13 00:00:00.000   2014-07-19 00:00:00.000    2
 2014-07-13 00:00:00.000   2014-07-19 00:00:00.000    2
 2014-07-20 00:00:00.000   2014-07-26 00:00:00.000    1

Query2结果集(部分):

reportstartdate reportenddate   ClosedCallCt
2014-07-06 00:00:00.000 2014-07-12 00:00:00.000 1
2014-07-13 00:00:00.000 2014-07-19 00:00:00.000 1
2014-07-20 00:00:00.000 2014-07-26 00:00:00.000 1

如何只使用查询获取以下结果集,而不使用中间表??

所需的结果集(部分):

reportstartdate reportenddate   OpenedCallCt    ClosedCallCt
2014-07-06 00:00:00.000 2014-07-12 00:00:00.000 2   1
2014-07-13 00:00:00.000 2014-07-19 00:00:00.000 2   1
2014-07-20 00:00:00.000 2014-07-26 00:00:00.000 1   1

感谢您提供任何帮助,如果您需要更多信息,请与我们联系。

2 个答案:

答案 0 :(得分:1)

SELECT ct.call_date
   , DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + (CAST(DATEPART(YY, ct.call_date) AS CHAR(4)))) + ((DATEPART(WK, ct.call_date)) - 1), 6) AS reportstartdate
   , DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + (CAST(DATEPART(YY, ct.call_date) AS CHAR(4)))) + ((DATEPART(WK, ct.call_date)) - 1), 5) AS reportenddate
   , count(*) OVER (PARTITION BY datepart(week, ct.call_date)) AS OpenedCallCt
   , count(case when ct.status > 3 then 1 end) OVER (PARTITION BY datepart(week, ct.call_date)) AS ClosedCallCt   
FROM calltable ct
WHERE ct.call_date <= @ReportEndDate
   AND ct.call_date >= dateadd(day, (- 7 * @WeeksBack), @ReportEndDate)

答案 1 :(得分:0)

基于原始示例提出的解决方案将会正常工作,前提是这是一次性报告。如果您希望报告无论@ReportEndDate还是@WeeksBack都能正常工作,那么您可能需要考虑这个解决方案:

http://www.sqlfiddle.com/#!3/ab18a4/9/0