首先,感谢帮助我解决这个问题的任何人。我正在使用SQL 2005,但如果05中没有可用的解决方案,则可以使用2008。
我有一行看起来像这样的数据:
select * from mySPtable
| myPK | Area | RequestType | StartDate | EndDate |
1 SB ADD 8/14/2011 8/18/2011
2 NB RMV 8/16/2011 8/16/2011
所以我想做的是按天计算每个区域的总请求数。结果应该是:
| myDate | RequestType | Area | myCount |
8/14/2011 ADD SB 1
8/15/2011 ADD SB 1
8/16/2011 ADD SB 1
8/16/2011 RMV NB 1
8/17/2011 ADD SB 1
8/18/2011 ADD SB 1
我该怎么做呢?我很难过,没有任何谷歌搜索帮助。
答案 0 :(得分:10)
您需要一个日历表,或者您可以使用CTE生成一个。一旦你有了,那么查询的其余部分应该是相当简单的。由于递归问题而且不允许使用聚合,CTE方法可能有点复杂,所以下面我使用了表变量。您还可以将其保存为数据库中的永久表。
SET NOCOUNT ON
DECLARE @Calendar TABLE (my_date DATETIME NOT NULL)
DECLARE @date DATETIME, @max_date DATETIME
SELECT @date = MIN(StartDate), @max_date = MAX(EndDate) FROM My_Table
WHILE (@date <= @max_date)
BEGIN
INSERT INTO @Calendar (my_date) VALUES (@date)
SELECT @date = DATEADD(dy, 1, @date)
END
SELECT
C.myDate,
M.RequestType,
M.Area,
COUNT(*) AS myCount
FROM
@Calendar C
INNER JOIN My_Table M ON
M.StartDate <= C.myDate AND
M.EndDate >= C.myDate
GROUP BY
C.myDate,
M.RequestType,
M.Area
ORDER BY
C.myDate,
M.RequestType,
M.Area
根据潜在日期范围的大小,填写表变量可能需要一段时间。例如,如果范围跨越十年或两年。
答案 1 :(得分:3)
听起来你可能需要'Calendar' file。特别是作为一个大型企业组织的一部分,这将变得非常有用。
生成日历后,您可以使用以下内容获取表格:
SELECT a.isoDate, b.RequestType, b.Area, count(*)
FROM calendar as a
JOIN mySPTable as b
ON a.isoDate between b.StartDate and b.EndDate
WHERE a.isoDate >= [input_start_date]
AND a.isoDate < [input_end_date]
GROUP BY a.isoDate, b.RequestType, b.Area
这将为日历文件中的每个日期生成一行,该行位于mySPTable的至少一行的开始日期和结束日期之间。
作为旁注,也可以使用递归CTE生成日期范围,但特别是从长远来看,我建议生成并使用日历文件。
快速CTE:
WITH DateRange (thisDate) as (SELECT [input_start_date]
UNION ALL
SELECT DATEADD(dy, 1, thisDate)
FROM DateRange
WHERE thisDate < [input_end_date])
答案 2 :(得分:2)
您可以使用数字表(从0开始)执行此操作。这里我使用master..spt_values代替。 SQL, Auxiliary table of numbers
select dateadd(day, N.Number, M.StartDate) as myDate,
RequestType,
Area,
count(*) as myCount
from mySPtable as M
inner join master..spt_values as N
on N.Number <= datediff(day, M.StartDate, M.EndDate)
where N.type = 'P'
group by dateadd(day, N.Number, M.StartDate),
RequestType,
Area
order by dateadd(day, N.Number, M.StartDate)