【发布时间】:2015-03-16 06:58:22
【问题描述】:
我想要一个查询返回不存在的行的值,以帮助制定统计查询。我相信共享样本是最简单的。这是我的超小样本日期集:
category date ID
Swimming 2013-02-09 1
Hiking 2013-05-01 2
Archery 2013-07-03 3
Swimming 2013-08-05 4
Swimming 2013-08-22 5
Archery 2013-09-01 6
Swimming 2013-09-18 7
NULL 2013-09-19 8
我现在的查询:
DECLARE @startdate DATETIME = '04/01/2013'
DECLARE @enddate DATETIME = '10/31/2013'
DECLARE @activitycategory VARCHAR(40) = 'Swimming'
SELECT category AS 'Activity'
,CASE WHEN category is null THEN 'No Category'
ELSE category
END as ActivityCategory
,DATEPART(yyyy,date) AS 'Year'
,DATEPART(mm,date) AS 'Month'
,COUNT(ID) AS 'Total Activities'
FROM classes
WHERE date BETWEEN @startdate AND @enddate
AND category IN (@activitycategory)
GROUP BY category
,DATEPART(yyyy,date)
,DATEPART(mm,date)
ORDER BY category
,DATEPART(yyyy,date)
,DATEPART(mm,date)
我的查询目前产生以下结果:
Activity ActivityCategory Year Month Total Activities
Swimming Swimming 2013 8 2
Swimming Swimming 2013 9 1
我想要以下结果:
Activity ActivityCategory Year Month Total Activities
Swimming Swimming 2013 4 0
Swimming Swimming 2013 5 0
Swimming Swimming 2013 6 0
Swimming Swimming 2013 7 0
Swimming Swimming 2013 8 2
Swimming Swimming 2013 9 1
Swimming Swimming 2013 10 0
我做了很多研究,看来我需要使用递归 CTE。我发现了一个我认为显然是必要的“日期范围”函数(除了有日历表之外)。我只是想不通了解如何编写最终查询..您会注意到我的查询需要具有参数能力..(最终这将是一个 SSRS 报告)..无论用户选择什么,没有返回行的计数都会产生一个如果“总活动”在所选日期范围内不存在,则为“0”。任何帮助表示赞赏。这是我找到的函数:
CREATE FUNCTION [dbo].[DateRange]
(
@Increment CHAR(1),
@StartDate DATETIME,
@EndDate DATETIME
)
RETURNS
@SelectedRange TABLE
(IndividualDate DATETIME)
AS
BEGIN
;WITH cteRange (DateRange) AS (
SELECT @StartDate
UNION ALL
SELECT
CASE
WHEN @Increment = 'd' THEN DATEADD(dd, 1, DateRange)
WHEN @Increment = 'w' THEN DATEADD(ww, 1, DateRange)
WHEN @Increment = 'm' THEN DATEADD(mm, 1, DateRange)
END
FROM cteRange
WHERE DateRange <=
CASE
WHEN @Increment = 'd' THEN DATEADD(dd, -1, @EndDate)
WHEN @Increment = 'w' THEN DATEADD(ww, -1, @EndDate)
WHEN @Increment = 'm' THEN DATEADD(mm, -1, @EndDate)
END)
INSERT INTO @SelectedRange (IndividualDate)
SELECT DateRange
FROM cteRange
OPTION (MAXRECURSION 3660);
RETURN
END
GO
提前致谢!
【问题讨论】:
-
为什么您认为需要递归 CTE? (在我的测试中,递归 CTE 是解决这个问题的最糟糕的解决方案。)日历表有什么问题?甚至是一个月的表?最后,please stop using lazy shorthand for date parts 和 be very careful with regional date formats。
-
@AaronBertrand - 链接确实有助于更好地编码。
标签: sql sql-server-2008 common-table-expression date-range