获取存储过程中两个日期时间之间的时间差

时间:2012-10-02 16:56:25

标签: sql-server stored-procedures

我希望在stroed过程中获得两个日期时间之间的时间差。然后我需要将答案转换为varchar。我不知道如何获得这个价值。我是一个新的stroed程序。我正在使用sql server 2008

declare @tdate1 datetime
declare @date2 datetime
declare @finaltime varchar

set @enddate = '2004-10-18 07:53:35.000'
set @startdate = '2004-10-18 15:28:57.000'

if @startdate >= @enddate
// This is what i want to do..

else

5 个答案:

答案 0 :(得分:17)

SELECT DATEDIFF(year, @startdate, @enddate)

试着这个让你朝着正确的方向前进。

year代表您想要返回的衡量时间

Here是指向可能有用的MSDN文章的链接

DATEDIFF(Transact-SQL)

其他版本

更新日期:2015年12月2日

此主题适用于:

yesSQL Server(从2008年开始)yesAzure SQL数据库yesAzure SQL数据仓库yesParallel数据仓库 返回指定的startdate和enddate之间交叉的指定datepart边界的计数(有符号整数)。 有关较大的差异,请参阅DATEDIFF_BIG(Transact-SQL)。有关所有Transact-SQL日期和时间数据类型和函数的概述,请参阅日期和时间数据类型和函数(Transact-SQL)。 主题链接图标Transact-SQL语法约定 语法

DATEDIFF ( datepart , startdate , enddate )

- Azure SQL数据仓库和并行数据仓库

DATEDIFF (datepart ,startdate ,enddate )

<强>参数

日期部分

startdate和enddate的部分是否指定了交叉边界的类型。下表列出了所有有效的datepart参数。用户定义的变量等效项无效。

<强>日期部分

缩写

year
yy, yyyy
quarter
qq, q
month
mm, m
dayofyear
dy, y
day
dd, d
week
wk, ww
hour
hh
minute
mi, n
second
ss, s
millisecond
ms
microsecond
mcs
nanosecond
ns
startdate

是一个可以解析为time, date, smalldatetime, datetime, datetime2或datetimeoffset值的表达式。 date可以是表达式,列表达式,用户定义的变量或字符串文字。从enddate中减去startdate。

为避免歧义,请使用四位数年份。有关两位数年份的信息,请参阅配置两位数年份截止服务器配置选项。 结束日期

参见 startdate 返回类型 INT 回报价值 每个datepart及其缩写返回相同的值。 如果返回值超出int(-2,147,483,648到+2,147,483,647)的范围,则返回错误。对于毫秒,startdate和enddate之间的最大差异是24天,20小时,31分钟和23.647秒。第二,最大差异是68年。 如果startdate和enddate都只分配了一个时间值,而datepart不是时间datepart,则返回0。 startdate或endate的时区偏移分量不用于计算返回值。 由于smalldatetime仅精确到分钟,因此当smaldatetime值用于startdate或enddate时,返回值中的秒和毫秒始终设置为0。 如果仅为日期数据类型的变量分配时间值,则缺少日期部分的值将设置为默认值:1900-01-01。如果仅为时间或日期数据类型的变量分配日期值,则将缺失时间部分的值设置为默认值:00:00:00。如果startdate或enddate只有一个时间部分而另一个只有一个日期部分,则缺少的时间和日期部分将设置为默认值。 如果startdate和enddate具有不同的日期数据类型,并且一个具有比另一个更多的时间部分或小数秒精度,则另一个的缺失部分设置为0。 datepart边界 以下语句具有相同的startdate和相同的endate。这些日期相邻,时间差异为.0000001秒。每个语句中startdate和endate之间的差异跨越其datepart的一个日历或时间边界。每个语句返回1.如果此示例使用不同的年份,并且startdate和endate都在同一个日历周中,则week的返回值将为0.

SELECT DATEDIFF(year, '2005-12-31 23:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(quarter, '2005-12-31 23:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(month, '2005-12-31 23:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(dayofyear, '2005-12-31 23:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(day, '2005-12-31 23:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(week, '2005-12-31 23:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(hour, '2005-12-31 23:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(minute, '2005-12-31 23:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(second, '2005-12-31 23:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(millisecond, '2005-12-31 23:59:59.9999999'
, '2006-01-01 00:00:00.0000000');

备注 DATEDIFF可以在选择列表,WHERE,HAVING,GROUP BY和ORDER BY子句中使用。 DATEDIFF隐式地将字符串文字强制转换为datetime2类型。这意味着当日期作为字符串传递时,DATEDIFF不支持格式YDM。必须将字符串显式转换为datetime或smalldatetime类型才能使用YDM格式。 指定SET DATEFIRST对DATEDIFF没有影响。 DATEDIFF总是使用星期日作为一周的第一天,以确保功能是确定性的。 例子 以下示例使用不同类型的表达式作为startdate和enddate参数的参数。 A.指定startdate和enddate的列 以下示例计算表中两列中日期之间交叉的日期边界数。

CREATE TABLE dbo.Duration
    (
    startDate datetime2
    ,endDate datetime2
    );
INSERT INTO dbo.Duration(startDate,endDate)
    VALUES('2007-05-06 12:10:09','2007-05-07 12:10:09');
SELECT DATEDIFF(day,startDate,endDate) AS 'Duration'
FROM dbo.Duration;

- 返回:1 B.为startdate和enddate指定用户定义的变量 以下示例使用用户定义的变量作为startdate和enddate的参数。

DECLARE @startdate datetime2 = '2007-05-05 12:10:09.3312722';
DECLARE @enddate datetime2 = '2007-05-04 12:10:09.3312722'; 
SELECT DATEDIFF(day, @startdate, @enddate);

℃。为startdate和enddate指定标量系统函数 以下示例使用标量系统函数作为startdate和enddate的参数。

SELECT DATEDIFF(millisecond, GETDATE(), SYSDATETIME());

d。为startdate和enddate指定标量子查询和标量函数 以下示例使用标量子查询和标量函数作为startdate和enddate的参数。 使用AdventureWorks2012; GO

SELECT DATEDIFF(day,(SELECT MIN(OrderDate) FROM Sales.SalesOrderHeader),
    (SELECT MAX(OrderDate) FROM Sales.SalesOrderHeader));

电子。指定startdate和enddate的常量 以下示例使用字符常量作为startdate和enddate的参数。

SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635'
    , '2007-05-08 09:53:01.0376635');

F。为enddate指定数字表达式和标量系统函数 以下示例使用数值表达式(GETDATE()+ 1)和标量系统函数GETDATE和SYSDATETIME作为enddate的参数。

USE AdventureWorks2012;
GO
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', GETDATE()+ 1) 
    AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO
USE AdventureWorks2012;
GO
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', DATEADD(day,1,SYSDATETIME())) AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO
G. Specifying ranking functions for startdate
The following example uses a ranking function as an argument for startdate.
USE AdventureWorks2012;
GO
SELECT p.FirstName, p.LastName
    ,DATEDIFF(day,ROW_NUMBER() OVER (ORDER BY 
        a.PostalCode),SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson s 
    INNER JOIN Person.Person p 
        ON s.BusinessEntityID = p.BusinessEntityID
    INNER JOIN Person.Address a 
        ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL 
    AND SalesYTD <> 0;

小时。为startdate指定聚合窗口函数 以下示例使用聚合窗口函数作为startdate的参数。

USE AdventureWorks2012;
GO
SELECT soh.SalesOrderID, sod.ProductID, sod.OrderQty,soh.OrderDate
    ,DATEDIFF(day,MIN(soh.OrderDate) 
        OVER(PARTITION BY soh.SalesOrderID),SYSDATETIME() ) AS 'Total'
FROM Sales.SalesOrderDetail sod
    INNER JOIN Sales.SalesOrderHeader soh
        ON sod.SalesOrderID = soh.SalesOrderID
WHERE soh.SalesOrderID IN(43659,58918);
GO

示例:Azure SQL数据仓库公共预览和并行数据仓库 以下示例使用不同类型的表达式作为startdate和enddate参数的参数。 I.指定startdate和enddate的列 以下示例计算表中两列中日期之间交叉的日期边界数。

CREATE TABLE dbo.Duration (
    startDate datetime2
    ,endDate datetime2
    );
INSERT INTO dbo.Duration(startDate,endDate)
    VALUES('2007-05-06 12:10:09','2007-05-07 12:10:09');
SELECT TOP(1) DATEDIFF(day,startDate,endDate) AS Duration
FROM dbo.Duration;

- 返回:1 J.为startdate和enddate指定标量子查询和标量函数 以下示例使用标量子查询和标量函数作为startdate和enddate的参数。 - 使用AdventureWorks

SELECT TOP(1) DATEDIFF(day,(SELECT MIN(HireDate) FROM dbo.DimEmployee),
    (SELECT MAX(HireDate) FROM dbo.DimEmployee)) 
FROM dbo.DimEmployee;

ķ。指定startdate和enddate的常量 以下示例使用字符常量作为startdate和enddate的参数。

-- Uses AdventureWorks

SELECT TOP(1) DATEDIFF(day, '2007-05-07 09:53:01.0376635'
    , '2007-05-08 09:53:01.0376635') FROM DimCustomer;

升。指定startdate的排名函数 以下示例使用排名函数作为startdate的参数。 - 使用AdventureWorks

SELECT FirstName, LastName
,DATEDIFF(day,ROW_NUMBER() OVER (ORDER BY 
        DepartmentName),SYSDATETIME()) AS RowNumber
FROM dbo.DimEmployee;

微米。为startdate指定聚合窗口函数 以下示例使用聚合窗口函数作为startdate的参数。 - 使用AdventureWorks

SELECT FirstName, LastName, DepartmentName
    ,DATEDIFF(year,MAX(HireDate)
             OVER (PARTITION BY DepartmentName),SYSDATETIME()) AS SomeValue
FROM dbo.DimEmployee

答案 1 :(得分:3)

结帐DATEDIFF。这是一个demo of how to use this

SELECT DATEDIFF(day, [Start], [End]) AS [Days],
   DATEDIFF(minute, [Start], [End]) AS [Minutes],
   DATEDIFF(second, [Start], [End]) AS [Seconds] FROM Dates;

答案 2 :(得分:1)

假设你想要计算两个日期之间的差异,这是我的建议:

DECLARE @start DATETIME = '01-01-2000', 
      @end DATETIME = GETDATE() 

SELECT CAST(ABS(DATEDIFF(day, @end, @start)) AS VARCHAR(100)) 

我认为你总是想要一个肯定的答案,所以ABS允许你忽略日期的顺序。你在帖子中提到你想要最终答案为Varchar,所以我加入了一个演员。

希望这会对你有所帮助。

答案 3 :(得分:1)

使用DATEDIFF()你可以得到秒差,分钟差,小时差等.....但是如果你想以清晰的方式得到日期/时间差,你可以做这种事情。

declare @StartDate datetime, @EndDate datetime

select @StartDate = '04/07/2015 05:01:23.000',@EndDate='04/08/2015 10:32:30.000'

select convert(varchar(5),DateDiff(s, @startDate, @EndDate)/3600)+':'+convert(varchar(5),DateDiff(s, @startDate, @EndDate)%3600/60)+':'+convert(varchar(5),(DateDiff(s, @startDate, @EndDate)%60)) as [HH:MM:SS]

输出格式为[HH:MM:SS]:05:31:07

我认为这是在SQL中获取两个日期时间之间时差的最佳方法

答案 4 :(得分:0)

这是我之前使用的,非常短的代码:

选择CAST((@ EndDateTime- @ StartDateTime)作为时间(0))'[hh:mm:ss]'