T-SQL 2 Tips: 1.计算任意两日期之间的"周一"到"周日"分别各有几个! 2.根据出生..

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

先说第二个:

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

时间: 2024-10-18 10:43:46

T-SQL 2 Tips: 1.计算任意两日期之间的&amp;quot;周一&amp;quot;到&amp;quot;周日&amp;quot;分别各有几个! 2.根据出生..的相关文章

Java中计算任意两个日期之间的工作天数

主要思路: 对于任意2个日期比如:date_start=2006-10-1.date_end=2006-10-14 ,首先计算这连个日期之间的时间间隔(天数),然后分别对date_start 和date_end 取得它们下一个星期一的日期,这样就可以得到一个新的可以整除7的完整日期间隔(这个新的日期间隔已经把星期几的问题剔出掉了),换一种说法就是我们可以得到,这两个新的日期之间的周数,拿这个周数乘以5就是工作日期了(tmpWorkingDays).但是这个日期并不是我们所要的日期,接下来我们要做

用单循环链表存储一个环上的数据,并计算任意两个相邻元素之差是否超过2

#include<iostream.h> #include<stdlib.h>   typedef struct node{   int  data;  struct node *next; }Lnode,*LinkList;   //假设下面的单循环链表均为带头结点,而且L指向尾结点.   void CreatLinkList(LinkList &L) {//建立一个单循环链表L,数据为整数,数据由键盘随机输入.  int i;  LinkList head;  L=(L

PostgreSQL 计算 任意类型 字段之间的线性相关性

PostgreSQL自带了计算numeric和numeric字段的线性相关性的聚合函数corr(numeric, numeric).例如: postgres=# select corr(c1,c2) from (values (1,2),(2,1),(100,90),(13,13),(25,27) ) t(c1,c2); corr ------------------- 0.998528203831946 (1 row) postgres=# \df+ corr List of function

mysql两日期之间数据查询语句

 代码如下 复制代码 SELECT * FROM `cangku` WHERE ((shijian>='2011-1-13′) and (shijian<='2011-1-20′)) 查询当前月的数据:  代码如下 复制代码 select * from tables where month(Date)=month(now()) 很简单吧,第一种还可以利用between来实现,这里我也不说了自己测试吧.

SQL Server利用HashKey计算列解决宽字段查询的性能问题

SQL Server利用HashKey计算列解决宽字段查询的性能问题 主人翁        本文主人翁:MSSQL菜鸟和MSSQL老鸟. 问题提出        某年某月某日,某MSSQL菜鸟满脸愁容的跑到老鸟跟前,心灰意懒的对老鸟说"我最近遇到一个问题,很大的问题,对,非常大的问题".老鸟不急不慢的推了推2000度超级近视眼镜框,慢吞吞的说:"说来听听".        "我有一个100万数据量的表,有一个宽度为7500字段,不幸的是现在我需要根据这个字

link用循环计算两个日期之间有多少工作日

问题描述 link用循环计算两个日期之间有多少工作日 用循环计算两个日期之间有多少工作日,link怎么实现?用takewhile怎么代替while? 解决方案 不考虑过节和轮休,写一个给你 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class P

sql 日期相减DATEDIFF()返回两日期天数

sql 日期相减DATEDIFF()返回两日期天数 定义和用法 DATEDIFF() 函数返回两个日期之间的天数. 语法 DATEDIFF(date1,date2)date1 和 date2 参数是合法的日期或日期/时间表达式. 注释:只有值的日期部分参与计算. DATEDIFF(expr1,expr2): returns expr1 - expr2 as a value in days 实例一 SELECT DATEDIFF('2008-12-30','2008-12-29') AS Diff

[华为机试练习题]54.判断任意两台计算机的IP地址是否属于同一子网络

题目 描述: 子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据. 最为简单的理解就是两台计算机各自的IP地址与子网掩码进行AND运算后,如果得出的结果是相同的,则说明这两台计算机是处于同一个子网络上的,可以进行直接的通讯.就这么简单. 请看以下示例: 运算演示之一: IP地址:192.168.0.1 子网掩码:255.255.255.0 AND运算 转化为二进制进行运算: IP地址:11010000.10101000.00000000.00000001 子网掩码:1111111

DirectX:函数可以连接任意两个filter

函数可以连接任意两个filter HRESULT ConnectFilters( IBaseFilter *pSrc, IBaseFilter *pDest ) { IPin *pIn = 0; IPin *pOut = 0; IEnumPins *pOutEnum; IEnumPins *pInEnum; PIN_DIRECTION ThisPinDir; HRESULT hr = pSrc->EnumPins( &pOutEnum ); hr = pDest->EnumPins(