我有以下似乎完美的工作,除了它总是比我需要的数量少1:
DECLARE @start_day DATETIME;
DECLARE @end_day DATETIME;
DECLARE @start_time DATETIME;
DECLARE @end_time DATETIME;
SET @start_day = '2013-06-03';
SET @end_day = '2013-06-07';
PRINT DATEDIFF(d, @start_day, @end_day)
- DATEDIFF(wk, @start_day, @end_day) * 2
- CASE
WHEN DATEPART(dw, @start_day) != 7 AND DATEPART(dw, @end_day) = 7 THEN 1
WHEN DATEPART(dw, @start_day) = 7 AND DATEPART(dw, @end_day) != 7 THEN -1
ELSE 0
END
我应该
`5` for `2013-06-03` to `2013-06-07` but it's giving me `4`.
`5` for `2013-06-03` to `2013-06-08` but it's giving me `4`.
`5` for `2013-06-03` to `2013-06-09` but it's giving me `4`.
`6` for `2013-06-03` to `2013-06-10` but it's giving me `5`.
所以我的问题是:
我如何获得:
`2013-06-03` to `2013-06-07` to equal 5
`2013-06-03` to `2013-06-08` to equal 5
`2013-06-03` to `2013-06-09` to equal 5
`2013-06-03` to `2013-06-10` to equal 6
请注意,在结尾添加+1并不能解决问题!!!
答案 0 :(得分:1)
Create table foo (
StartDate datetime not null,
EndDate datetime not null
)
insert into foo (StartDate, EndDate) values (N'2013-06-03', N'2013-06-07'),
(N'2013-06-03', N'2013-06-08'),
(N'2013-06-03', N'2013-06-09'),
(N'2013-06-03', N'2013-06-10')
SELECT
DATEDIFF(d, StartDate, EndDate)
+ CASE
WHEN DATEPART(dw, StartDate) <= 5 THEN 1
ELSE 0
END
- DATEDIFF(wk, StartDate, EndDate) * 2
- CASE
WHEN DATEPART(dw, StartDate) != 7 AND DATEPART(dw, EndDate) = 7 THEN 1
WHEN DATEPART(dw, StartDate) = 7 AND DATEPART(dw, EndDate) != 7 THEN -1
ELSE 0
END
FROM foo
答案 1 :(得分:0)
如果您想要复制Excel的NETWORKDAYS,那么我在很久以前写过这个......
CREATE FUNCTION [dbo].[fnNetworkDays]
(
@date1 SMALLDATETIME,
@date2 SMALLDATETIME
)
RETURNS INT
AS
BEGIN
DECLARE @ret INT,
@dt1 INT,
@dt2 INT,
@dt3 INT,
@neg INT,
@wks INT,
@dyo INT,
@wkd INT,
@take INT
--Midnightise the dates
SELECT @date1 = DATEADD(dd,0, DATEDIFF(dd,0,@date1)), @date2 = DATEADD(dd,0, DATEDIFF(dd,0,@date2))
--Get integers to make the calcs easier
SELECT @dt1 = CONVERT(INT,@date1),@dt2 = CONVERT(INT,@date2)
IF @dt1 > @dt2
BEGIN
SET @neg = -1
SET @dt3 = @dt1
SET @dt1 = @dt2
SET @dt2 = @dt3
END
ELSE
SET @neg = 1
SET @ret = @dt2 - @dt1 + 1
SET @wks = FLOOR(@ret / 7)
SET @dyo = @ret % 7
SET @wkd = @dt1 % 7
SELECT @take=CASE @wkd
WHEN 0 THEN CASE WHEN @dyo = 6 THEN 1 ELSE 0 END
WHEN 6 THEN CASE WHEN @dyo = 1 THEN 1 ELSE 0 END
ELSE CASE WHEN @dyo = (6 - @wkd) THEN 1 ELSE CASE WHEN @dyo > (6 - @wkd) THEN 2 ELSE 0 END END
END
SELECT @ret = @neg * (@ret - @wks * 2 - @take)
RETURN @ret
END
可能过于复杂但有效。
答案 2 :(得分:0)
我宁愿使用带有计数表的COUNT。
SELECT COUNT(*)
FROM dbo.tTally
WHERE n BETWEEN DATEDIFF(dd, 0, @from) AND DATEDIFF(dd, 0, @to)
AND DATEPART(dw, DATEADD(dd, n, 0)) NOT IN (7, 1)