致歉: 由于《T-SQL 2 Tips》有错,请相关用户速打此补丁: K4-911 !
经人举报
《T-SQL 2 Tips: 1.计算任意两日期之间的"周一"到"周日"分别各有几个! 2.根据出生日期计算精确年龄! 》
http://blog.csdn.net/playyuer/archive/2004/08/20/79699.aspx
http://dev.csdn.net/develop/article/33/33740.shtm
http://community.csdn.net/Expert/TopicView.asp?id=3294180
"1.计算任意两日期之间的"周一"到"周日"分别各有几个" 有错!
经核查,部分属实!
1.关于"跨周数",我已经声名:"周日算作上周的最后一天!",因此的确与 zjcxc(邹建) 以及 SQL 的默认规则不符!因此在一些情况下,三个答案"跨周数"查询结果不一致!但"不能算错误"!予以驳回!
下面是重新汇总的 3 个正确答案,我又写了一个答案,一共 3 个答案,第三个答案是zjcxc(邹建)的
,均与 datefirst 无关!
declare @b datetime,@e datetime
set @b = '2004-9-14'
set @e = '2004-9-15'
--2004-09-11 新方法
select
@b as 开始日期
,@e as 结束日期
,datediff(week,@b,@e) + 1
+ case when (@@datefirst + datepart(weekday,@b)) % 7 = 1 then 1 else 0 end
- case when (@@datefirst + datepart(weekday,@e)) % 7 = 1 then 1 else 0 end as 跨周数
,datediff(week,@b,@e) + case when (@@datefirst + datepart(weekday,@b)) % 7 + case when (@@datefirst + datepart(weekday,@b)) % 7 = 0 then 7 else 0 end > 2 then 0 else 1 end - case when (@@datefirst + datepart(weekday,@e)) % 7 + case when (@@datefirst + datepart(weekday,@e)) % 7 = 0 then 7 else 0 end >= 2 then 0 else 1 end as 周一数
,datediff(week,@b,@e) + case when (@@datefirst + datepart(weekday,@b)) % 7 + case when (@@datefirst + datepart(weekday,@b)) % 7 = 0 then 7 else 0 end > 3 then 0 else 1 end - case when (@@datefirst + datepart(weekday,@e)) % 7 + case when (@@datefirst + datepart(weekday,@e)) % 7 = 0 then 7 else 0 end >= 3 then 0 else 1 end as 周二数
,datediff(week,@b,@e) + case when (@@datefirst + datepart(weekday,@b)) % 7 + case when (@@datefirst + datepart(weekday,@b)) % 7 = 0 then 7 else 0 end > 4 then 0 else 1 end - case when (@@datefirst + datepart(weekday,@e)) % 7 + case when (@@datefirst + datepart(weekday,@e)) % 7 = 0 then 7 else 0 end >= 4 then 0 else 1 end as 周三数
,datediff(week,@b,@e) + case when (@@datefirst + datepart(weekday,@b)) % 7 + case when (@@datefirst + datepart(weekday,@b)) % 7 = 0 then 7 else 0 end > 5 then 0 else 1 end - case when (@@datefirst + datepart(weekday,@e)) % 7 + case when (@@datefirst + datepart(weekday,@e)) % 7 = 0 then 7 else 0 end >= 5 then 0 else 1 end as 周四数
,datediff(week,@b,@e) + case when (@@datefirst + datepart(weekday,@b)) % 7 + case when (@@datefirst + datepart(weekday,@b)) % 7 = 0 then 7 else 0 end > 6 then 0 else 1 end - case when (@@datefirst + datepart(weekday,@e)) % 7 + case when (@@datefirst + datepart(weekday,@e)) % 7 = 0 then 7 else 0 end >= 6 then 0 else 1 end as 周五数
,datediff(week,@b,@e) + case when (@@datefirst + datepart(weekday,@b)) % 7 + case when (@@datefirst + datepart(weekday,@b)) % 7 = 0 then 7 else 0 end > 7 then 0 else 1 end - case when (@@datefirst + datepart(weekday,@e)) % 7 + case when (@@datefirst + datepart(weekday,@e)) % 7 = 0 then 7 else 0 end >= 7 then 0 else 1 end as 周六数
,datediff(week,@b,@e) + case when (@@datefirst + datepart(weekday,@b)) % 7 + case when (@@datefirst + datepart(weekday,@b)) % 7 = 0 then 7 else 0 end > 1 then 0 else 1 end - case when (@@datefirst + datepart(weekday,@e)) % 7 + case when (@@datefirst + datepart(weekday,@e)) % 7 = 0 then 7 else 0 end >= 1 then 0 else 1 end as 周日数
select @b as 开始日期,@e as 结束日期,
datediff(week
,case when datename(weekday,@b) = '星期日' then @b - 1
else @b end
,case when datename(weekday,@e) = '星期日' then @e - 1
else @e end
) + 1 as 跨周数
,datediff(week
,case when datename(weekday,@b) = '星期日' then @b - 1
else @b end
,case when datename(weekday,@e) = '星期日' then @e - 1
else @e end
) + 1
- case when datename(weekday,@b) in ('星期二','星期三','星期四','星期五','星期六','星期日') then 1
else 0 end
as 周一数
,datediff(week
,case when datename(weekday,@b) = '星期日' then @b - 1
else @b end
,case when datename(weekday,@e) = '星期日' then @e - 1
else @e end
) + 1
- case when datename(weekday,@b) in ('星期三','星期四','星期五','星期六','星期日') then 1
else 0 end
- case when datename(weekday,@e) in ('星期一') then 1
else 0 end
as 周二数
,datediff(week
,case when datename(weekday,@b) = '星期日' then @b - 1
else @b end
,case when datename(weekday,@e) = '星期日' then @e - 1
else @e end
) + 1
- case when datename(weekday,@b) in ('星期四','星期五','星期六','星期日') then 1
else 0 end
- case when datename(weekday,@e) in ('星期一','星期二') then 1
else 0 end
as 周三数
,datediff(week
,case when datename(weekday,@b) = '星期日' then @b - 1
else @b end
,case when datename(weekday,@e) = '星期日' then @e - 1
else @e end
) + 1
- case when datename(weekday,@b) in ('星期五','星期六','星期日') then 1
else 0 end
- case when datename(weekday,@e) in ('星期一','星期二','星期三') then 1
else 0 end
as 周四数
,datediff(week
,case when datename(weekday,@b) = '星期日' then @b - 1
else @b end
,case when datename(weekday,@e) = '星期日' then @e - 1
else @e end
) + 1
- case when datename(weekday,@b) in ('星期六','星期日') then 1
else 0 end
- case when datename(weekday,@e) in ('星期一','星期二','星期三','星期四') then 1
else 0 end
as 周五数
,datediff(week
,case when datename(weekday,@b) = '星期日' then @b - 1
else @b end
,case when datename(weekday,@e) = '星期日' then @e - 1
else @e end
) + 1
- case when datename(weekday,@b) in ('星期日') then 1
else 0 end
- case when datename(weekday,@e) in ('星期一','星期二','星期三','星期四','星期五') then 1
else 0 end
as 周六数
,datediff(week
,case when datename(weekday,@b) = '星期日' then @b - 1
else @b end
,case when datename(weekday,@e) = '星期日' then @e - 1
else @e end
) + 1
- case when datename(weekday,@e) in ('星期一','星期二','星期三','星期四','星期五','星期六') then 1
else 0 end
as 周日数
--zjcxc(邹建)
--查询方式1(纵向)
select
项目='跨周数'
,值=case when @b<@e
then (datediff(day,@b,@e)+7)/7
else (datediff(day,@e,@b)+7)/7 end
union all
select a.a,case b.a
when -1 then case when a.b between b.b and b.c then 1 else 0 end
when 0 then case when b.b<=a.b then 1 else 0 end
+case when b.c>=a.b then 1 else 0 end
else b.a+case when b.b<=a.b then 1 else 0 end
+case when b.c>=a.b then 1 else 0 end
end
from(select a='星期一',b=1
union all select '星期二',2 union all select '星期三',3
union all select '星期四',4 union all select '星期五',5
union all select '星期六',6 union all select '星期日',0
)a,(select a=case when @b<@e
then datediff(week,@b,@e)-1
else datediff(week,@e,@b)-1 end
,b=case when @b<@e
then (@@datefirst+datepart(weekday,@b)-1)%7
else (@@datefirst+datepart(weekday,@e)-1)%7 end
,c=case when @b<@e
then (@@datefirst+datepart(weekday,@e)-1)%7
else (@@datefirst+datepart(weekday,@b)-1)%7 end
)b
2.zjcxc(邹建)的 "查询方式2(横向)",在起止日期连续时的确有错误!相信我汇报之后很快就会改好!