Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 需要计算截止日期的年、月和日_Sql_Sql Server_Sql Server 2008_Date - Fatal编程技术网

Sql 需要计算截止日期的年、月和日

Sql 需要计算截止日期的年、月和日,sql,sql-server,sql-server-2008,date,Sql,Sql Server,Sql Server 2008,Date,我有一张叫dates的桌子 Opendate | Closedate ------------+--------------- 2015-07-09 | 2016-08-10 我期待的结果是 opendate | closedate | diff ------------+---------------+---------------------- 2015-07-09 | 2016-08-10 | 1year 1month 1d

我有一张叫dates的桌子

Opendate    |   Closedate   
------------+---------------
2015-07-09  |   2016-08-10  
我期待的结果是

opendate    |   closedate   |   diff    
------------+---------------+----------------------
2015-07-09  |   2016-08-10  |   1year 1month 1day   
2015-07-09  |   2016-03-01  |   8 months 20 days
2015-07-09  |   2015-07-11  |   2 days
opendate    |   closedate   | years | months |  days    
------------+---------------+-------+--------+---------
2015-07-09  |   2016-08-10  |   1   |   13   |  397 
但当我运行此查询时:

SELECT opendate, 
       closedate, 
       Datediff(year, opendate, closedate)  AS years, 
       Datediff(month, opendate, closedate) AS months, 
       Datediff(day, opendate, closedate)   AS days 
FROM   dates 
它给了我一个输出,比如

opendate    |   closedate   |   diff    
------------+---------------+----------------------
2015-07-09  |   2016-08-10  |   1year 1month 1day   
2015-07-09  |   2016-03-01  |   8 months 20 days
2015-07-09  |   2015-07-11  |   2 days
opendate    |   closedate   | years | months |  days    
------------+---------------+-------+--------+---------
2015-07-09  |   2016-08-10  |   1   |   13   |  397 
我们如何计算1年1月1日

SELECT opendate, 
       closedate, 
       ( ( Datediff(year, opendate, closedate) +  'years' )+  
       (( Datediff(month, opendate, closedate) - 
             12 * Datediff(year, opendate, closedate)) + 'months') +
        ( Datediff(day, opendate, closedate) - 
         ( Datediff(year, opendate, closedate) * 365 - 
         (Datediff(month, opendate, closedate) * 12) )) + 'days'

FROM   dates 

逻辑是将年份串联起来,然后减去一年中的月数。同样扣除天数

您可以使用堆叠CTE逐个查找下一年、下一个月和下一个日期

解释

下面的查询首先找出opendate和closedate的
DATEDIFF
年份,并检查结果日期是否大于closedate。如果是,实际年份差异为Y-1的
DATEDIFF
。使用此新日期,使用相同的逻辑获取月份的
DATEDIFF
,然后以天为单位获取差值

查询

WITH D(Opendate,Closedate)AS
(
SELECT CAST('2015-07-09' AS DATE),CAST('2016-08-10' AS DATE)
UNION ALL 
SELECT CAST('2015-07-09' AS DATE),CAST('2016-03-01' AS DATE)
UNION ALL 
SELECT CAST('2015-07-09' AS DATE),CAST('2015-07-11' AS DATE)

),Y AS
(
SELECT Opendate,Closedate,
  CASE 
  WHEN DATEADD(YEAR,DATEDIFF(YEAR,Opendate,Closedate),Opendate) > Closedate 
  THEN DATEDIFF(YEAR,Opendate,Closedate) - 1 
  ELSE DATEDIFF(YEAR,Opendate,Closedate)
  END Years
FROM D
), YDate as 
(
SELECT Opendate,Closedate,Years,DATEADD(YEAR,Years,Opendate) as Newopendate
FROM Y
),M AS
(
SELECT Opendate,Closedate,Years,Newopendate,
CASE WHEN DATEADD(MONTH,DATEDIFF(MONTH,Newopendate,Closedate),Newopendate) > Closedate 
THEN DATEDIFF(MONTH,Newopendate,Closedate) - 1 
ELSE DATEDIFF(MONTH,Newopendate,Closedate) 
END Months
FROM YDate
) 
SELECT Opendate,Closedate,Years,Months,DATEDIFF(Day,DATEADD(MONTH,Months,Newopendate),Closedate) as days
FROM M
结果

Opendate    Closedate   Years   Months  days
09-07-2015 00:00    10-08-2016 00:00    1   1   1
09-07-2015 00:00    01-03-2016 00:00    0   7   21
09-07-2015 00:00    11-07-2015 00:00    0   0   2

创建一个函数,如下所示

 CREATE FUNCTION dbo.GetYearMonthDays
    (
       @FromDate DATETIME
    )
    RETURNS NVARCHAR(100)
    AS
    BEGIN
       DECLARE @date datetime, @tmpdate datetime, @years int, @months int, @days int
       SELECT @date =@FromDate

    SELECT @tmpdate = @date

    SELECT @years = DATEDIFF(yy, @tmpdate, GETDATE()) - CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE())) THEN 1 ELSE 0 END
    SELECT @tmpdate = DATEADD(yy, @years, @tmpdate)
    SELECT @months = DATEDIFF(m, @tmpdate, GETDATE()) - CASE WHEN DAY(@date) > DAY(GETDATE()) THEN 1 ELSE 0 END
    SELECT @tmpdate = DATEADD(m, @months, @tmpdate)
    SELECT @days = DATEDIFF(d, @tmpdate, GETDATE())

        RETURN  CONVERT(varchar(10), @years) +' Years   ' +  CONVERT(varchar(10), @months)  + ' Month  ' + CONVERT(varchar(10), @days) + ' Days'
    END
    GO
使用方法如下

SELECT opendate, 
       closedate,dbo.GetYearMonthDays(closedate)
FROM   dates

这会给你你想要的。

关闭日期
2016-03-01
@Prdp时结果应该是什么?当关闭日期
2015-07-11
时结果应该是
2天mind@prdp一点也不,实际上是好消息245,将varchar值“years”转换为数据类型int时,级别16,状态1,第11行转换失败。