我需要一个SQL查询循环,日期减少日期.
StartDate : 3/15/2015 [Date param] [MM/dd/yyyy]
EndDate : 3/5/2015 [Date param]
Operation : Decrement by a day toward EndDate
BreakDate : 3/10/2015 [Date param]
Run Code Online (Sandbox Code Playgroud)
当前日期(循环)应从开始日期到结束日期打印一天减量
如果到达中断日期,那么循环应该自行停止[内部循环]
以上输入的示例结果:
3/15/2015
3/14/2015
3/13/2015
3/11/2015
3/10/2015
Run Code Online (Sandbox Code Playgroud)
请帮忙.
你不需要循环.你永远不应该用这种心态处理SQL中的问题,它应该是最后的手段.
如果使用日期,那么最简单的解决方案是使用日历表,如果你没有创建日历表,那么你可以使用:
DECLARE @StartDate DATE = '20150315',
@EndDate DATE = '20150305',
@BreakDate DATE = '20150310';
SELECT Date
FROM Calendar
WHERE Date <= @StartDate
AND Date > @EndDate
AND Date > @BreakDate;
Run Code Online (Sandbox Code Playgroud)
但是,我很欣赏创建日历表并不总是一个选项,但是可以很容易地生成日期列表.来自以下文章:
动态执行此操作的最佳方法是使用常量的交叉连接(在文章中称为Stacked CTE).这只是从一个10行的表值构造函数开始,交叉连接到它自己获得100行,然后再次获得100x100 = 10,000行,依此类推:
DECLARE @StartDate DATE = '20150315',
@EndDate DATE = '20150305',
@BreakDate DATE = '20150310';
WITH N1 (N) AS (SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
N3 (N) AS (SELECT 1 FROM N2 AS N1 CROSS JOIN N2 AS N2),
N4 (N) AS (SELECT ROW_NUMBER() OVER(ORDER BY N1.N) FROM N3 AS N1 CROSS JOIN N3 AS N2)
SELECT Date = DATEADD(DAY, 1 - N, @StartDate)
FROM N4
WHERE N <= DATEDIFF(DAY, @EndDate, @StartDate) + 1
AND N <= DATEDIFF(DAY, @BreakDate, @StartDate) + 1;
Run Code Online (Sandbox Code Playgroud)
编辑
如果您的休息日期可以在开始日期之后,那么您只需要一些额外的逻辑来解决这个问题,因此您的查询将变为:
DECLARE @StartDate DATE = '20150315',
@EndDate DATE = '20150305',
@BreakDate DATE = '20150310';
SELECT Date
FROM Calendar
WHERE Date <= @StartDate
AND Date > @EndDate
AND ( Date > @BreakDate
OR @BreakDate >= @StartDate
);
Run Code Online (Sandbox Code Playgroud)
要么
DECLARE @StartDate DATE = '20150315',
@EndDate DATE = '20150305',
@BreakDate DATE = '20150320';
WITH N1 (N) AS (SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
N3 (N) AS (SELECT 1 FROM N2 AS N1 CROSS JOIN N2 AS N2),
N4 (N) AS (SELECT ROW_NUMBER() OVER(ORDER BY N1.N) FROM N3 AS N1 CROSS JOIN N3 AS N2)
SELECT Date = DATEADD(DAY, 1 - N, @StartDate)
FROM N4
WHERE N <= DATEDIFF(DAY, @EndDate, @StartDate) + 1
AND ( N <= DATEDIFF(DAY, @BreakDate, @StartDate) + 1
OR @BreakDate >= @StartDate
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1677 次 |
| 最近记录: |