邪恶八进制信息安全团队技术讨论组's Archiver

pub!1c 2006-4-24 13:15

[转载]SQL中的时间计算语句

<p>信息来源: <font color="#cc0000">IT 专家网</font></p><p style="TEXT-INDENT: 2em">问:请问专家,如何计算一个表中的周起始和截止日期并写到表字段中?我要从一个表向另一个表导入数据,并进行转换,用的是VB 。 </p><p><font face="Verdana">  我现在有有一个表 主要字段有<br /><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3">time_id int<br />time_date datetime<br />year int<br />week_of_year int<br />day nvarhar<br /></td></tr></tbody></table>  想要转换成另外一张表<br /><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3">time_id int<br />time_date datetime<br />year int<br />week_of_year nvarchar<br /></td></tr></tbody></table>  原来的表内容是<br /><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3">--------------------<br />1 2003-07-09 2003 20 星期日<br />1 2003-07-10 2003 20 星期一<br />1 2003-07-11 2003 20 星期二</td></tr></tbody></table></font></p><p><font face="Verdana">  想要变成<br /><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3">--------------------<br />1 07/09/2003 2003 第20周(7/9-7/17) <br />1 07/10/2003 2003 第20周(7/9-7/17) <br />1 07/11/2003 2003 第20周(7/9-7/17) <br /></td></tr></tbody></table>  请专家指点,这个语句应该怎么去写?</font></p><p><font face="Verdana">  答: <table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3"><font face="Verdana">if object_id('tablename') is not null drop table tablename<br />select 1 as time_id, '2003-07-09' as time_date, 2003 as [year], 20 as week_of_year, '星期日' as [day]<br />into tablename<br />union select 1, '2003-07-10', 2003, 20, '星期一'<br />union select 1, '2003-07-11', 2003, 20, '星期二'<br />------------------------------------------------<br />select time_id, time_date, [year], '第' + cast(week_of_year as varchar(2)) + '周(' <br /> + cast(month(week_begin) as varchar(2)) + '/' + cast(day(week_begin) as varchar(2)) + '-'<br /> + cast(month(week_end) as varchar(2)) + '/' + cast(day(week_end) as varchar(2)) as week_of_year<br />from (select *, dateadd(day, 1 - datepart(weekday, time_date), time_date) as week_begin, <br /> dateadd(day, 7 - datepart(weekday, time_date), time_date) as week_end from tablename) a<br />/*<br />time_id time_date year week_of_year<br />1 2003-07-09 2003 第20周(7/6-7/12)<br />1 2003-07-10 2003 第20周(7/6-7/12)<br />1 2003-07-11 2003 第20周(7/6-7/12)<br />*/<br />------------------------------------------------<br />drop table tablename</font><font face="Verdana"> <p><br /></p></font></td></tr></tbody></table></font></p><p style="TEXT-INDENT: 2em">问题虽然解决了,但这个例子并不具备通用性,还是个案,所以我们分析了你的代码,发现一个问题:日期范围是如何确定的?所以,我们把它延伸发散到:能否自主设定日期的范围呢?比如设定到星期一或星期天开始:</p><p><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3"><p>思路:<br />SET DATEFIRST<br />将一周的第一天设置为从 1 到 7 之间的一个数字。</p><p>语法<br />SET DATEFIRST { number | @number_var } </p><p>参数<br />number | @number_var</p><p>是一个整数,表示一周的第一天,可以是下列值中的一个。</p><p>值 一周的第一天是 <br />1 星期一 <br />2 星期二 <br />3 星期三 <br />4 星期四 <br />5 星期五 <br />6 星期六 <br />7(默认值,美国英语) 星期日 </p><p><br />注释<br />使用 @@DATEFIRST 函数检查 SET DATEFIRST 的当前设置。</p><p>SET DATEFIRST 的设置是在执行或运行时设置,而不是在分析时设置。</p></td></tr></tbody></table><br />  <strong>方法一:<br /></strong></p><p><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3">先创建一个用户函数,根据日期得到周开始日期和结束日期<br />create function getwstend(@resultdate datetime)<br />returns varchar(20)<br />As<br />begin<br />declare @weekstart datetime,@weekend datetime,@dayweek int,@weeknum int<br />set @weeknum = datepart(wk,@resultdate)<br />set @dayweek = datepart(dw,@resultdate)<br />begin<br />set @weekstart = dateadd(dd,1-@dayweek,@resultdate)<br />set @weekend = DateAdd(dd,7-@dayweek,@resultdate)<br />end<br />return '第'+Convert(varchar,@weeknum)+'周'+'('+right(convert(varchar(10),@weekstart,111),5)+'--'+right(Convert(varchar(10),@weekend,111),5)+')'<br />end<br />Go <br />例如:<br />select test.getwstend('2006-4-17') <br />返回结果是:第16周(04/16--04/22)</td></tr></tbody></table>  利用这个函数相信就可以实现你的要求了,把所有表1中的数据转到表2</p><p>  <strong>方法二:</strong></p><p>  为了避免数据的冗余,建议不要把数据从第一个表转到第二个表。因为这样会造成数据冗余。你可以在查询时候使用函数产生week_of_year nvarchar 这个栏位。</p><p>  <strong>方法三:<br /></strong></p><p><table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr><td style="WORD-WRAP: break-word" bgcolor="#f3f3f3">创建一个表,栏位为:<br />create table tw<br />(<br /> time_date datetime,<br /> week_of_year nvarchar<br />)<br />然后1910.1.1---2050.12.31之间的所有日期都产生一个对照的week_of_year nvarchar,方法也是使用上面创建的函数。然后查询的时候。只要两个表作关联就可以了</td></tr></tbody></table>  如果原始表中的记录很多。而且日期有很多重复,我们更推荐使用方法三。<br /></p>

页: [1]
© 1999-2008 EvilOctal Security Team