数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
T-SQL 2 Tips: 1.计算任意两日期之间的"周一"到"周日"分别各有几个! 2.根据出生日期计算精确年龄!

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

这两个小技巧,不写不知道,一写吓一跳!
都是看似简单,实际做起来就懵,得仔细想一想,才能写对!
凡是有日期运算的程序都要细心哦!

先说第二个:

2.根据出生日期精确计算年龄!
  所谓计算精确年龄就是: 生日差一天也不能长一岁!
  大家常用,间隔年数算作年龄! 如果需求要精确,如: 保险 之类的,就粗了!
  当然还可引申为根据入职日期计算精确的司龄,算加薪之类的需求!
  我起初认为很简单,当年也写了好几遍才写对!高手们也被我晃点了数次几近晕倒!
  不信有当年 2002-11-27 16:16:26 贴子为证:

  《我的表中有字段出生年月日,请问怎样根据当前日期计算该人的年龄,并填充到表的相应字段内?》
   http://search.csdn.net/expert/topicview1.asp?id=1210302

  书归正传:

declare @Birthday smalldatetime
set @Birthday ='1949-6-5'

--多用一个日期变量,为了扩展: 计算将来或过去某一时刻的当时的精确年龄 的功能!
declare @ smalldatetime
set @ = getdate()

select datediff(year,@Birthday,@)
       + case when dateadd(year,datediff(year,@Birthday,@),@Birthday) <= @
                   then 1
              else 0
         end

再说第一个:
1.计算任意两日期之间的 周一 到 周日 分别各有几个!
   起因来自该贴:
  《SQL语句求当月的上班天数》
   http://community.csdn.net/Expert/TopicView1.asp?id=3291510

   本来想偷懒 Google 一下,没有满意的结果,好像他自己也没底!思路也不一样!
  《求一尖酸的算法》(有点儿同感,说起来简单,做起来就晕)
   http://www.itpub.net/252645.html

   顺便说一下,我写程序总想写的"更通用"一些,可能答非所问了!


由于 @@datefirst 可通过 set datefirst N 设定 导致 datepart(weekday,[date]) 不确定!
所以用 datename!
因为确定的日期是周几肯定是永远不变的!当然不随 datefirst 变!
所以更要用 datename!
另外按着中国人的习惯: 周日算作上周的最后一天!
如果是其他语言版本的 SQL Server 注意选用该语言版本的 周几 的形式!

declare @b datetime
declare @e datetime

set @b = '2004-07-29'
set @e = '2004-08-05'

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 周日个数

--哇塞终于搞定了,起初没想到的是: 竟然着实动了一番脑筋!

剩下的就是用的人可以为所欲为地将他变成 UDF SP (View) 等了!
如果你真正理解了我的思路,就可以用任何一种语言实现!

最后再作一下广告:
http://www.microshaoft.com
http://www.csdn.net/Develop/list_article.asp?author=playyuer

送你几个巨长的 SQL,也许狠有用,点一下,帮我加点儿人气:

T-SQL 生成 两个新的真正的公历年历
http://www.csdn.net/Develop/Read_Article.asp?Id=26447


T-SQL 生成一个简易的 公历年历 T-SQL 含日期所在月及年的周次
http://www.csdn.net/Develop/Read_Article.asp?Id=26083


http://www.microshaoft.com
http://www.csdn.net/Develop/list_article.asp?author=playyuer




相关文章

相关软件