GVKun编程网logo

基于来自多行SQL Server的标志的时间总和

11

在这篇文章中,我们将带领您了解基于来自多行SQLServer的标志的时间总和的全貌,同时,我们还将为您介绍有关C#执行SQLServer的NonQuerySQL文件、SQLServer一次性压缩Sql

在这篇文章中,我们将带领您了解基于来自多行SQL Server的标志的时间总和的全貌,同时,我们还将为您介绍有关C#执行SQL Server的NonQuery SQL文件、SQL Server 一次性压缩Sqlserver2005中所有库日志的存储过程、SQL Server 中查看SQL句子执行所用的时间、SQL Server 中的时间算法的知识,以帮助您更好地理解这个主题。

本文目录一览:

基于来自多行SQL Server的标志的时间总和

基于来自多行SQL Server的标志的时间总和

我很难执行查询之一。我需要根据同一张表中的标志找到点火时间。表格如下

UnitId      eventtime               ign----------- ----------------------- -----356         2011-05-04 10:41:00.000 1356         2011-05-04 10:42:00.000 1356         2011-05-04 10:43:00.000 1356         2011-05-04 10:45:00.000 1356         2011-05-04 10:47:00.000 1356         2011-05-04 10:48:00.000 0356         2011-05-04 11:14:00.000 1356         2011-05-04 11:14:00.000 1356         2011-05-04 11:15:00.000 1356         2011-05-04 11:15:00.000 1356         2011-05-04 11:15:00.000 1356         2011-05-04 11:16:00.000 0356         2011-05-04 11:16:00.000 0356         2011-05-04 11:16:00.000 0356         2011-05-04 14:49:00.000 1356         2011-05-04 14:50:00.000 1356         2011-05-04 14:50:00.000 1356         2011-05-04 14:51:00.000 1356         2011-05-04 14:52:00.000 0356         2011-05-04 14:52:00.000 0356         2011-05-04 20:52:00.000 0

在此,Ign标志将确定ignition_on和iginition_off时间。所以上表我们可以得到点火对

2011-05-04 10:41:00.000 - 2011-05-04 10:48:00.0002011-05-04 11:14:00.000 - 2011-05-04 11:16:00.0002011-05-04 14:49:00.000 - 2011-05-04 14:52:00.000

因此,从上面的对来看,我可以说我的设备运行了7 + 2 + 3 = 12分钟。我不希望上述结果是对的,仅作为示例。我的目的是得到12分钟的结果。

我如何使用单个查询来实现它,现在我正在使用CURSOR循环,但是这件事需要花费更多的时间才能使用多天和多个单元。无论如何,在没有CURSOR的情况下我可以实现它吗?

答案1

小编典典

如果还有其他标准可以区分具有相同ign值的连续事件序列,则可以从每个序列中获取ign=1最早的事件,并将其与相应ign=0序列的最早事件联系起来。

可以添加这样的标准,如下所示。我将首先发布该解决方案,然后解释其工作原理。

首先,设置:

DECLARE @atable TABLE (  Id int IDENTITY,  UnitId int,  eventtime datetime,  ign bit);INSERT INTO @atable (UnitId, eventtime, ign)SELECT 356, ''2011-05-04 10:41:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 10:42:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 10:43:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 10:45:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 10:47:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 10:48:00.000'', 0 UNION ALLSELECT 356, ''2011-05-04 11:14:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 11:14:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 11:15:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 11:15:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 11:15:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 11:16:00.000'', 0 UNION ALLSELECT 356, ''2011-05-04 11:16:00.000'', 0 UNION ALLSELECT 356, ''2011-05-04 11:16:00.000'', 0 UNION ALLSELECT 356, ''2011-05-04 14:49:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 14:50:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 14:50:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 14:51:00.000'', 1 UNION ALLSELECT 356, ''2011-05-04 14:52:00.000'', 0 UNION ALLSELECT 356, ''2011-05-04 14:52:00.000'', 0 UNION ALLSELECT 356, ''2011-05-04 20:52:00.000'', 0;

现在查询:

WITHmarked AS (  SELECT    *,    Grp = ROW_NUMBER() OVER (PARTITION BY UnitId ORDER BY eventtime) -     ROW_NUMBER() OVER (PARTITION BY UnitId, ign ORDER BY eventtime)  FROM @atable),ranked AS (  SELECT    *,    seqRank = DENSE_RANK() OVER (PARTITION BY UnitId, ign ORDER BY Grp),    eventRank = ROW_NUMBER() OVER (PARTITION BY UnitId, ign, Grp ORDER BY eventtime)  FROM marked),final AS (  SELECT    s.UnitId,    EventStart = s.eventtime,    EventEnd   = e.eventtime  FROM ranked s    INNER JOIN ranked e ON s.UnitId = e.UnitId AND s.seqRank = e.seqRank  WHERE s.ign = 1    AND e.ign = 0    AND s.eventRank = 1    AND e.eventRank = 1)SELECT *FROM finalORDER BY  UnitId,  EventStart

这就是它的工作方式。

marked公用表表达式(CTE)为我们提供了我说的是在开始的附加标准。它产生的结果集如下所示:

Id  UnitId  eventtime                ign  Grp--  ------  -----------------------  ---  ---1   356     2011-05-04 10:41:00.000  1    02   356     2011-05-04 10:42:00.000  1    03   356     2011-05-04 10:43:00.000  1    04   356     2011-05-04 10:45:00.000  1    05   356     2011-05-04 10:47:00.000  1    06   356     2011-05-04 10:48:00.000  0    57   356     2011-05-04 11:14:00.000  1    18   356     2011-05-04 11:14:00.000  1    19   356     2011-05-04 11:15:00.000  1    110  356     2011-05-04 11:15:00.000  1    111  356     2011-05-04 11:15:00.000  1    112  356     2011-05-04 11:16:00.000  0    1013  356     2011-05-04 11:16:00.000  0    1014  356     2011-05-04 11:16:00.000  0    1015  356     2011-05-04 14:49:00.000  1    416  356     2011-05-04 14:50:00.000  1    417  356     2011-05-04 14:50:00.000  1    418  356     2011-05-04 14:51:00.000  1    419  356     2011-05-04 14:52:00.000  0    1420  356     2011-05-04 14:52:00.000  0    1421  356     2011-05-04 20:52:00.000  0    14

您可以自己了解如何ign通过其自己的键轻松地将具有相同事件的每个事件序列与其他事件区分开(UnitId, ign,Grp)。因此,现在我们可以对每个序列以及序列中的每个事件进行排名,这就是rankedCTE所做的。它产生以下结果集:

Id  UnitId  eventtime                ign  Grp  seqRank  eventRank--  ------  -----------------------  ---  ---  -------  ---------1   356     2011-05-04 10:41:00.000  1    0    1        12   356     2011-05-04 10:42:00.000  1    0    1        23   356     2011-05-04 10:43:00.000  1    0    1        34   356     2011-05-04 10:45:00.000  1    0    1        45   356     2011-05-04 10:47:00.000  1    0    1        56   356     2011-05-04 10:48:00.000  0    5    1        17   356     2011-05-04 11:14:00.000  1    1    2        18   356     2011-05-04 11:14:00.000  1    1    2        29   356     2011-05-04 11:15:00.000  1    1    2        310  356     2011-05-04 11:15:00.000  1    1    2        411  356     2011-05-04 11:15:00.000  1    1    2        512  356     2011-05-04 11:16:00.000  0    10   2        113  356     2011-05-04 11:16:00.000  0    10   2        214  356     2011-05-04 11:16:00.000  0    10   2        315  356     2011-05-04 14:49:00.000  1    4    3        116  356     2011-05-04 14:50:00.000  1    4    3        217  356     2011-05-04 14:50:00.000  1    4    3        318  356     2011-05-04 14:51:00.000  1    4    3        419  356     2011-05-04 14:52:00.000  0    14   3        120  356     2011-05-04 14:52:00.000  0    14   3        221  356     2011-05-04 20:52:00.000  0    14   3        3

您可以看到,借助,ign=1现在可以将ign=0序列与序列匹配seqRank。并且仅从每个序列中选择最早的事件(按过滤eventRank=1),我们将获得所有ign=1序列的开始时间和结束时间。因此,finalCTE的结果是:

UnitId  EventStart               EventEnd------  -----------------------  -----------------------356     2011-05-04 10:41:00.000  2011-05-04 10:48:00.000356     2011-05-04 11:14:00.000  2011-05-04 11:16:00.000356     2011-05-04 14:49:00.000  2011-05-04 14:52:00.000

显然,如果最后一个ign=1序列后面没有ign=0事件,则不会在最终结果中显示它,因为使用上述方法,最后一个ign=1序列将没有匹配的ign=0序列。

在一种可能的情况下,此查询将无法正常使用。这是事件列表以ign=0事件而不是开头的时间ign=1。如果确实可行,则只需将以下过滤器添加到rankedCTE:

WHERE NOT (ign = 0 AND Grp = 0)-- Alternatively: WHERE ign <> 0 OR Grp <> 0

利用以下事实:的第一个值Grp将始终为0。因此,如果0将分配给具有ign=0的事件,则应排除这些事件。

C#执行SQL Server的NonQuery SQL文件

C#执行SQL Server的NonQuery SQL文件

首先要在项目里引入以下3个dll文件:

    Microsoft.SqlServer.ConnectionInfo.dll

    Microsoft.SqlServer.Management.Sdk.Sfc.dll

    Microsoft.SqlServer.Smo.dll

然后在代码里引入以下两个using:

using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;

可以写代码了

 //从SQL文件获取SQL语句
 FileInfo objFileInfo = new FileInfo(strFileFullPath);
 string SqlScript = objFileInfo.OpenText().ReadToEnd();
 //初始化SSMS,注意要先创建连接
 Server objServer = new Server(new ServerConnection(objSqlConn));
 //执行SQL语句
 objServer.ConnectionContext.ExecuteNonQuery(SqlScript);

  

这三个dll缺一不可,他们构成了一个极简化的SSMS,然后将SQL文件转化成SQL语句传给这个极简化的SSMS执行就可以了。

SQL Server 一次性压缩Sqlserver2005中所有库日志的存储过程

SQL Server 一次性压缩Sqlserver2005中所有库日志的存储过程

感兴趣的小伙伴,下面一起跟随小编 jb51.cc的小编两巴掌来看看吧!

有没有办法更快一点?
有没有办法一次性收缩所有数据库?

代码如下:

 
alter database 数据库名 
set recovery simple 
go 
dbcc shrinkdatabase (数据库名) 
go 
alter database 数据库名 
set recovery full 
go 

目前也有压缩日志的工具,一个B/S界面形式的操作压缩数据库的,就是在选择数据库的时候老需要重新去选择具体的库,而且数据库数量很大的时候,有些库被压缩了,并没有自动排序; 目前需要的是被压缩后的数据库自动滚到最后面,每次下拉列表中打开的始终是日志记录容量最大的那个库,这个容易实现,要求就是执行日志压缩的时候,执行速度要快些?
如何优化?有没有办法一次性压缩所有的库?
通过存储过程实现,一次性压缩所有数据库:在sqlserver2005中测试通过

代码如下:

 
create procedure shrinkDatabase 
as 
declare @name nvarchar(2000) 
declare getDataBaseCursor cursor for 
select name from sysdatabases //取出所有库名 
open getDataBaseCursor 
fetch next from getDataBaseCursor 
into @name //将取出来的值放在一个变量中 
while @@fetch_status=0 //根据值循环执行压缩 
begin 
exec ('alter database '+ @name+' set recovery simple') 
exec ('dbcc shrinkdatabase('+@name+')') 
exec ('alter database'+@name+' set recovery full') 
fetch next from getDataBaseCursor 
into @name end 
close getDataBaseCursor //关闭 
deallocate getDataBaseCursor //释放 
sp_helpdb urltest //比对数据库大小 
exec shrinkDatabase //执行 

SQL Server 中查看SQL句子执行所用的时间

SQL Server 中查看SQL句子执行所用的时间

感兴趣的小伙伴,下面一起跟随小编 jb51.cc的小编两巴掌来看看吧!

代码如下:

set statistics profile on 
set statistics io on 
set statistics time on 
go 

你执行的sql语句

代码如下:

go 
set statistics profile off 
set statistics io off 
set statistics time off 


执行完后点消息即可。
 

SQL Server 中的时间算法

SQL Server 中的时间算法

DECLARE @Date DATETIME SET @Date=GETDATE() --前一天,给定日期的前一天 SELECT DATEADD(DAY,-1,@Date) AS ''前一天'' --后一天,给定日期的后一天 SELECT DATEADD(DAY,1,@Date) AS ''后一天'' GO --月初,计算给定日期所在月的第一天 --这个计算的技巧是先计

  declare @date datetime

  SET @Date=GETDATE()

  --前一天,给定日期的前一天

  SELECT DATEADD(DAY,-1,@Date) AS ''前一天''

  --后一天,给定日期的后一天

  SELECT DATEADD(DAY,1,@Date) AS ''后一天''

  GO

  --月初,计算给定日期所在月的第一天

  --这个计算的技巧是先计算当前日期到“1900-01-01”的时间间隔数,然后把它加到“1900-01-01”上来获得特殊的日期,这个技巧可以用---来计算很多不同的日期。

  declare @date datetime

  SET @Date=GETDATE()

  SELECT DATEADD(MONTH,DATEDIFF(MONTH,''1900-01-01'',@Date),''1900-01-01'') AS ''所在月的第一天''

  --精简算法,根据SQL Server的时间表示方式可知,''1900-01-01'' 可以用0代替

  SELECT DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0) AS ''所在月的第一天''

  --上面两种算法精确到天 时分秒均为00:00:00.000

  --下面算法课以保留时分秒

  --思路:用给定日期减去月第一天与给定日期差的天数

  SELECT DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)

  GO

  --月末,计算给定日期所在月的最后一天

  declare @date datetime

  SET @Date=GETDATE()

  --思路:当前月的下一月1号在减1天

  SELECT DATEADD(DAY,-1,DATEADD(MONTH,1+DATEDIFF(MONTH,''1900-01-01'',@Date),''1900-01-01'')) AS ''所在月的最一天''

  SELECT DATEADD(MONTH,1+DATEDIFF(MONTH,''1900-01-01'',@Date),''1900-01-01'')-1 AS ''所在月的最一天''

  --1900-01-01 用0代替

  SELECT DATEADD(DAY,-1,DATEADD(MONTH,1+DATEDIFF(MONTH,0,@Date),0)) AS ''所在月的最一天''

  SELECT DATEADD(MONTH,1+DATEDIFF(MONTH,0,@Date),0)-1 AS ''所在月的最一天''

  --思路:与月初计算思路相同

  SELECT DATEADD(MONTH,DATEDIFF(MONTH,''1989-12-31'',@Date),''1989-12-31'') AS ''所在月的最一天''

  --精简算法,''1989-12-31'' 用-1代替

  SELECT DATEADD(MONTH,DATEDIFF(MONTH,-1,@Date),-1) AS ''所在月的最一天''

  --保留时分秒的算法

  SELECT DATEADD(DAY,-1,DATEADD(MONTH,1,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)))

  GO

  --其他月计算

  --计算给定日期所在月的上月第一天

  declare @date datetime

  SET @Date=GETDATE()

  --当前月第一天减去一个月

  SELECT DATEADD(MONTH,-1,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0)) AS ''上月第一天''

  --简化

  SELECT DATEADD(MONTH,DATEDIFF(MONTH,0,@Date)-1,0) AS ''上月第一天''

  --另一种当前月第一天算法

  SELECT DATEADD(MONTH,-1,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)) ''上月第一天''

  GO

  --计算给定日期所在月的上月最后一天

  declare @date datetime

  SET @Date=GETDATE()

  --当前月第一天减去一天

  SELECT DATEADD(DAY,-1,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0)) AS ''上月最后一天''

  --另一种当前月第一天算法

  SELECT DATEADD(DAY,-1,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)) ''上月最后一天''

  SELECT DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)-1 ''上月最后一天''

  --另一种算法,不能用当前月的最后一天加一个月,因为当前月可能是30天。

  --例如 SELECT DATEADD(MONTH,1,''2010-06-30'') --结果是2010-07-30而不是2010-07-31,

  --这也是月末算法采用下月第一天减1天计算的原因

  --但是如果计算月是31天择无此问题

  --例如 SELECT DATEADD(MONTH,1,''2010-05-31'') --结果是2010-06-30

  --因此下面算法是正确的,-1 表示''1899-12-31 00:00:00.000''-- SELECT CONVERT(DATETIME,-1)

  SELECT DATEADD(MONTH,DATEDIFF(MONTH,-1,@Date)-1,-1)

  --另一种当前月算法

  SELECT DATEADD(DAY,-1,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)) ''上月最后一天''

  --简化

  SELECT DATEADD(DAY,0-DATEPART(DAY,@Date),@Date) ''上月最后一天''

  GO

  --计算给定日期所在月的下月第一天

  declare @date datetime

  SET @Date=GETDATE()

  --当前月第一天加一个月

  SELECT DATEADD(MONTH,1,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0)) AS ''下月第一天''

  --简化

  SELECT DATEADD(MONTH,DATEDIFF(MONTH,0,@Date)+1,0) AS ''下月第一天''

  --另一种当前月第一天算法

  SELECT DATEADD(MONTH,1,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date)) ''下月第一天''

  GO

  --计算给定日期所在月的下月最后一天

  declare @date datetime

  SET @Date=GETDATE()

  --当前月第一天加2个月再减去1天

  SELECT DATEADD(DAY,-1,DATEADD(MONTH,2,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0))) AS ''下月最后一天''

  --简化

  SELECT DATEADD(DAY,-1,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date)+2,0)) AS ''下月最后一天''

  SELECT DATEADD(MONTH,DATEDIFF(MONTH,0,@Date)+2,0)-1 AS ''下月最后一天''

  --另一种算法

  SELECT DATEADD(MONTH,DATEDIFF(MONTH,-1,@Date)+1,-1) ''下月最后一天''

  --另一种当前月第一天算法

  SELECT DATEADD(DAY,-1,DATEADD(MONTH,2,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date))) ''下月最后一天''

  GO

  --所在星期的第一天,计算给定日期所在星期的第1天(星期日为第一天)

  declare @date datetime

  SET @Date= GETDATE()

  --与SQL Server语言版本相关的算法

  --思路:当前日期+星期日(每周的第1天)与当前日期的差的天数

  --DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关

  SET DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)

  SELECT DATEADD(WEEKDAY,1-DATEPART(WEEKDAY,@Date),@Date) AS ''所在星期的第一天,星期日''

  --星期日,与SQL Server语言版本或@@DATEFIRST无关

  --''1989-12-31'' 是星期日,''1989-12-31'' 再加上(当前日期与1989-12-31差的星期数)个星期

  SELECT DATEADD(WEEK,DATEDIFF(WEEK,-1,@Date),-1) AS ''所在星期的星期日''

  --或者

  SELECT DATEADD(WEEK,DATEDIFF(WEEK,6,@Date),6) AS ''所在星期的星期日''

  GO

  --所在星期的第二天,计算给定日期所在星期的第2天(星期日为第一天)

  declare @date datetime

  SET @Date= GETDATE()

  --思路:当前日期+星期一(每周的第2天)与当前日期的差的天数

  --DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关

  SET DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)

  SELECT DATEADD(DAY,2-DATEPART(WEEKDAY,@Date),@Date) AS ''所在星期的第二天,星期一''

  --星期一,与SQL Server语言版本或@@DATEFIRST无关

  --''1900-01-01'' 是星期一,''1900-01-01'' 再加上(当前日期与1900-01-01差的星期数)个星期

  SELECT DATEADD(WEEK,DATEDIFF(WEEK,0,@Date),0) AS ''所在星期的星期一''

  GO

  --上个星期第一天,计算给定日期所在星期的上一个星期日(星期日为第一天)

  declare @date datetime

  SET @Date= GETDATE()

  --思路:当前日志所在星期的星期日再减1周

  --DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关

  SET DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)

  SELECT DATEADD(WEEK,-1,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS ''上个星期第一天,星期日''

  --一周等于7天

  SELECT DATEADD(DAY,-7,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS ''上个星期第一天,星期日''

  --简化

  SELECT DATEADD(DAY,-6-DATEPART(WEEKDAY,@Date),@Date) AS ''上个星期第一天,星期日''

  --上个星期日,与SQL Server语言版本或@@DATEFIRST无关

  SELECT DATEADD(WEEK,-1+DATEDIFF(WEEK,-1,@Date),-1) AS ''上个星期日''

  --或者

  SELECT DATEADD(WEEK,DATEDIFF(WEEK,6,@Date),-1) AS ''上个星期日''

  GO

  --下个星期第一天,计算给定日期所在星期的下一个星期日(星期日为第一天)

  declare @date datetime

  SET @Date= GETDATE()

  --思路:当前日志所在星期的星期日再加1周

  --DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关

  SET DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)

  SELECT DATEADD(WEEK,1,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS ''下个星期第一天,星期日''

  --一周等于7天

  SELECT DATEADD(DAY,7,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS ''下个星期第一天,星期日''

  --简化

  SELECT DATEADD(DAY,8-DATEPART(WEEKDAY,@Date),@Date) AS ''下个星期第一天,星期日''

  --下个星期日,与SQL Server语言版本或@@DATEFIRST无关

  SELECT DATEADD(WEEK,1+DATEDIFF(WEEK,-1,@Date),-1) AS ''下个星期日''

  --或者

  SELECT DATEADD(WEEK,DATEDIFF(WEEK,-1,@Date),6) AS ''下个星期日''

  GO

  --判断给定日期是星期几

  declare @date datetime

  SET @Date= GETDATE()

  --DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关

  SET DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)

  SELECT DATEPART(WEEKDAY,@Date) --返回值 1-星期日,2-星期一,3-星期二......7-星期六

  --上面算法与SQL 语言版本或 @@DATEFIRST 相关

  --下面算法与SQL Server语言版本或@@DATEFIRST无关

  SELECT DATENAME(WEEKDAY,@Date) ''星期''

  GO

  --年度计算

  declare @date datetime

  SET @Date=GETDATE()

  --年初,计算给定日期所在年的第一天

  SELECT DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),0) AS ''所在年的第一天''

  --年末,计算给定日期所在年的最后一天

  SELECT DATEADD(YEAR,DATEDIFF(YEAR,-1,@Date),-1) AS ''所在年的最后一天''

  --上一年年初,计算给定日期所在年的上一年的第一天

  SELECT DATEADD(YEAR,DATEDIFF(YEAR,-0,@Date)-1,0) AS ''所在年的上一年的第一天''

  --上一年年末,计算给定日期所在年的上一年的最后一天

  SELECT DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),-1) AS ''所在年的上一年的最后一天''

  --下一年年初,计算给定日期所在年的下一年的第一天

  SELECT DATEADD(YEAR,1+DATEDIFF(YEAR,0,@Date),0) AS ''所在年的下一年的第一天''

  --下一年年末,计算给定日期所在年的下一年的最后一天

  SELECT DATEADD(YEAR,1+DATEDIFF(YEAR,-1,@Date),-1) AS ''所在年的下一年的最后一天''

  GO

  --季度计算

  declare @date datetime

  SET @Date=GETDATE()

  --季度初,计算给定日期所在季度的第一天

  SELECT DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date),0) AS ''当前季度的第一天''

  --季度末,计算给定日期所在季度的最后一天

  SELECT DATEADD(QUARTER,1+DATEDIFF(QUARTER,0,@Date),-1) AS ''当前季度的最后一天''

  --上个季度初

  SELECT DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date)-1,0) AS ''当前季度的上个季度初''

  --上个季度末

  SELECT DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date),-1) AS ''当前季度的上个季度末''

  --下个季度初

  SELECT DATEADD(QUARTER,1+DATEDIFF(QUARTER,0,@Date),0) AS ''当前季度的下个季度初''

  --下个季度末

  SELECT DATEADD(QUARTER,2+DATEDIFF(QUARTER,0,@Date),-1) AS ''当前季度的下个季度末''

  --计算给定日期所在月的天数

  declare @date datetime;

  SET @Date = GETDATE()

  --本月度第一天与下月度第一天所差的天数

  SELECT DATEDIFF(DAY,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0),DATEADD(MONTH,1+DATEDIFF(MONTH,0,@Date),0))

  --借助变量简化

  SELECT @Date = DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0) --本月度第一天

  SELECT DATEDIFF(DAY,@Date,DATEADD(MONTH,1,@Date))

  --另一种思路:给定月最后一天的日期,,记为本月天数

  SELECT DAY(DATEADD(MONTH,DATEDIFF(MONTH,-1,@Date),-1))

  GO

  --计算给定日期所在季度的天数

  declare @date datetime;

  SET @Date = GETDATE()

  --本季度第一天与下季度第一天所差的天数

  SELECT DATEDIFF(DAY,DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date),0),DATEADD(QUARTER,1+DATEDIFF(QUARTER,0,@Date),0))

  --借助变量简化

  SELECT @Date = DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date),0) --本季度第一天

  SELECT DATEDIFF(DAY,@Date,DATEADD(QUARTER,1,@Date))

  GO

  --计算给定日期所在年度的天数

  declare @date datetime;

  SET @Date = GETDATE()

  --本年度第一天与下年度第一天所差的天数

  SELECT DATEDIFF(DAY,DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),0),DATEADD(YEAR,1+DATEDIFF(YEAR,0,@Date),0))

  --借助变量简化

  SELECT @Date = DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),0) --本年度第一天

  SELECT DATEDIFF(DAY,@Date,DATEADD(YEAR,1,@Date))

  GO

  --判断给定日期所在年是否闰年

  --根据全年总天数判断

  declare @date datetime;

  SET @Date = GETDATE()

  SELECT CASE DATEDIFF(DAY,DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),0),DATEADD(YEAR,1+DATEDIFF(YEAR,0,@Date),0))

  WHEN 365 THEN ''平年'' ELSE ''闰年'' END

  --根据二月天数判断

  --给日期的上一年最后一天加2个月,即为当年2月最后一天

  SELECT CASE DAY(DATEADD(MONTH,2,DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),-1))) WHEN 28 THEN ''平年'' ELSE ''闰年'' END

  GO

  --计算给定日期是当年的第几天

  declare @date datetime;

  SET @Date = GETDATE()

  SELECT DATEPART(DAYOFYEAR,@Date) [DayOfYear];

  SELECT DATENAME(DAYOFYEAR,@Date) [DayOfYear];

  --另一种思路:当前日期与上年最后一天差的天数

  SELECT DATEDIFF(DAY,DATEADD(YEAR,DATEDIFF(YEAR,0,@Date),-1),@Date)[DayOfYear]

  GO

  --计算给定日期是当年的第几周

  declare @date datetime;

  SET @Date = GETDATE()

  SELECT DATEPART(WEEK,@Date) [WeekOfYear]; --返回int型

  SELECT DATENAME(WEEK,@Date) [WeekOfYear]; --返回varchar型

  GO

  --计算给定日期是当年的第几月

  declare @date datetime;

  SET @Date = GETDATE()

  SELECT DATEPART(MONTH,@Date) [MonthOfYear]; --返回int型

  SELECT DATENAME(MONTH,@Date) [MonthOfYear]; --返回varchar型

  SELECT MONTH(@Date) [MonthOfYear];--返回int型

  GO

  --计算给定日期是当年的第几季度

  declare @date datetime;

  SET @Date = GETDATE()

  SELECT DATEPART(QUARTER,@Date) [QuarterOfYear]; --返回int型

  SELECT DATENAME(QUARTER,@Date) [QuarterOfYear]; --返回varchar型

  GO

  --计算给定日期是当月的第几周

  declare @date datetime;

  SET @Date = GETDATE()

  --思路,给定日期是当年的第几周-给定日期所在月第一天是当年的第几周

  SELECT DATEPART(WEEK,@Date)-DATEPART(WEEK,DATEADD(MONTH,DATEDIFF(MONTH,0,@Date),0))+1 [WeekOfMonth]

  SELECT DATEPART(WEEK,@Date)-DATEPART(WEEK,DATEADD(DAY,1-DATEPART(DAY,@Date),@Date))+1 [WeekOfMonth]

  GO

  --计算给定日期所在月的第一个星期一是哪天

  declare @date datetime;

  SET @Date = GETDATE()

  --思路,1900-01-01(星期一)加上(给定日志所在月的月6号与1900-01-01差的周数)个周

  --为什么不选7号?如果是7号,那么7好恰好是星期日的话,第一个周一就会算到8号。

  --为什么不选5号?如果5号是星期六,那么周一就跑到上月了。小于5号与这个道理一样。

  SELECT DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY,6-DATEPART(DAY,@Date),@Date)),0) ''所在月的第一个星期一''

  SELECT DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY,6-DATEPART(DAY,@Date),@Date)),7) ''所在月的第二个星期一''

  SELECT DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY,6-DATEPART(DAY,@Date),@Date)),1) ''所在月的第一个星期二''

  SELECT DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY,6-DATEPART(DAY,@Date),@Date)),8) ''所在月的第二个星期二''

  GO

关于基于来自多行SQL Server的标志的时间总和的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于C#执行SQL Server的NonQuery SQL文件、SQL Server 一次性压缩Sqlserver2005中所有库日志的存储过程、SQL Server 中查看SQL句子执行所用的时间、SQL Server 中的时间算法等相关知识的信息别忘了在本站进行查找喔。

本文标签: