我正在使用SQL Server 2012,并且具有一系列由一组业务规则定义的日期。
CREATE TABLE #end_of_week_range
([id] int, [year] int, [week] int, [first_day] datetime, [last_day] datetime);
INSERT INTO #end_of_week_range
([id], [year], [week], [first_day], [last_day])
VALUES
(1, 2014, 1, '2013-12-05 00:00:00', '2014-01-05 00:00:00'),
(2, 2015, 1, '2014-12-04 00:00:00', '2015-01-04 00:00:00'),
(3, 2014, 10, '2014-02-09 00:00:00', '2014-03-09 00:00:00'),
(4, 2015, 10, '2015-02-08 00:00:00', '2015-03-08 00:00:00'),
(5, 2014, 11, '2014-02-16 00:00:00', '2014-03-16 00:00:00'),
(6, 2015, 11, '2015-02-15 00:00:00', '2015-03-15 00:00:00'),
(7, 2014, 12, '2014-02-23 00:00:00', '2014-03-23 00:00:00'),
(8, 2015, 12, '2015-02-22 00:00:00', '2015-03-22 00:00:00'),
(9, 2014, 13, '2014-02-28 00:00:00', '2014-03-28 00:00:00'),
(10, 2015, 13, '2015-02-28 00:00:00', '2015-03-28 00:00:00');
-- Many more, see SQLFiddle
带有日期的销售记录。
CREATE TABLE #sales (id INT, saledate DATETIME);
INSERT INTO #sales (id, saledate)
VALUES
(1, '2014-02-08'),
(2, '2015-02-08'),
(3, '2015-02-08'),
(4, '2015-02-08'),
(5, '2015-02-08'),
(6, '2014-02-08'),
(7, '2014-02-08'),
(8, '2014-02-08'),
(9, '2015-02-08'),
(10, '2015-02-08'),
(11, '2015-07-08');
我想计算每个范围内的销售记录数,并获得此预期产出。
year week cnt
2014 6 4
2015 6 0
2014 7 4
2015 7 6
2014 8 4
2015 8 6
2014 9 4
2015 9 6
-- More rows, see SQLFiddle
我现在正在做的是循环遍历每个范围并过滤日期范围中的第一天和最后一天。
CREATE TABLE #sales_trended (
[year] INT
,[week] INT
,[cnt] INT
)
DECLARE @id INT
WHILE EXISTS (
SELECT *
FROM #end_of_week_range
)
BEGIN
SELECT TOP 1 @id = id
FROM #end_of_week_range
INSERT INTO #sales_trended
SELECT (
SELECT year
FROM #end_of_week_range
WHERE id = @id
) AS year
,(
SELECT week
FROM #end_of_week_range
WHERE id = @id
) AS week
,count(*) AS cnt
FROM #sales s
WHERE (
s.saledate >= (
SELECT first_day
FROM #end_of_week_range
WHERE id = @id
)
AND s.saledate < (
SELECT last_day
FROM #end_of_week_range
WHERE id = @id
)
)
DELETE #end_of_week_range
WHERE id = @id
END
SELECT *
FROM #sales_trended
我可以改为加入销售和日期范围表以及按日期范围分组而不是循环显示每个日期范围吗?我目前的方法看起来非常缓慢。
答案 0 :(得分:2)
不确定我是否正确理解了问题,但是您不能加入具有日期范围的表格,如下所示:
select e.year, e.week, count(s.id)
from end_of_week_range e
left outer join sales s on
s.saledate >= e.first_day and
s.saledate < e.last_day
group by e.year, e.week
order by e.year, e.week
编辑:糟糕,计数当然必须来自销售
答案 1 :(得分:2)
如果你正在使用SQL并且你认为你需要使用循环,那么你几乎总是在想错。
您可以通过简单的连接来完成此操作:
SELECT r.year,
r.week,
COUNT(s.id) as cnt
FROM end_of_week_range r
LEFT JOIN sales s
ON s.saledate >= r.first_day
AND s.saledate < r.last_day
GROUP BY r.year,
r.week
ORDER BY r.year,
r.week