Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.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
T-SQL计算不同年份范围之间的持续时间(以月为单位)_Sql_Sql Server_Tsql_Sql Server 2012_Sqldatetime - Fatal编程技术网

T-SQL计算不同年份范围之间的持续时间(以月为单位)

T-SQL计算不同年份范围之间的持续时间(以月为单位),sql,sql-server,tsql,sql-server-2012,sqldatetime,Sql,Sql Server,Tsql,Sql Server 2012,Sqldatetime,我在SQL Server中有一个表,其中包含用户为不同作业工作的持续时间。我需要计算用户体验的总数 Declare @temp table(Id int, FromDate DATETIME, ToDate DATETIME) INSERT INTO @temp ( Id ,FromDate ,ToDate ) VALUES ( 1 , '2003-1-08 06:55:56' , '2005-5-08 06:55:56'), ( 2 , '2000-10-08 06:55

我在SQL Server中有一个表,其中包含用户为不同作业工作的持续时间。我需要计算用户体验的总数

Declare @temp table(Id int, FromDate DATETIME, ToDate DATETIME)
INSERT INTO @temp ( Id ,FromDate ,ToDate )
VALUES   ( 1 , '2003-1-08 06:55:56' , '2005-5-08 06:55:56'),
         ( 2 , '2000-10-08 06:55:56' , '2008-7-08 06:55:56'),
         ( 3 , '2013-6-08 06:55:56' , '2015-1-08 06:55:56'),
         ( 4 , '2006-4-08 06:55:56' , '2011-3-08 06:55:56' )
SELECT * FROM @temp 
我想计算经验的总数

Id  FromDate    ToDate       Difference IN Months
===================================================
1   2003-01-08  2005-05-08    28
2   2000-10-08  2008-07-08    93
3   2013-06-08  2015-01-08    19
4   2006-04-08  2011-03-08    59
在2000-2008年消除了2003-2005年等重叠年份的掩盖之后; 我得到了这样的东西:

Id  FromDate    ToDate       Difference IN Months
===================================================    
1   2000-10-08  2011-03-08    125
2   2013-06-08  2015-01-08    19
因此答案是
125+19=144
monds。
请帮助我找到解决方案。

这里的语法是查找所有FromDate和ToDate间隔不重叠的FromDate,以及所有FromDate和ToDate间隔不重叠的ToDate。根据日期值为他们指定一个行号,并在该行号上匹配他们:

;WITH CTE as
(
  SELECT min(Id) Id ,FromDate, row_number() over (ORDER BY FromDate) rn
  FROM @temp x
  WHERE 
    not exists
      (SELECT * FROM @temp WHERE x.FromDate > FromDate and x.FromDate <= Todate)
  GROUP BY FromDate
), CTE2 as
(
  SELECT Max(Id) Id ,ToDate, row_number() over (ORDER BY ToDate) rn
  FROM @temp x
  WHERE
    not exists
      (SELECT * FROM @temp WHERE x.ToDate >= FromDate and x.ToDate < Todate)
  GROUP BY ToDate
)
SELECT SUM(DateDiff(month, CTE.FromDate, CTE2.ToDate))
FROM CTE
JOIN CTE2
ON CTE.rn = CTE2.rn
你可以试试这个

SELECT Set1.FromDate,MIN(List1.ToDate) AS ToDate, DATEDIFF(MONTH,Set1.FromDate,MIN(List1.ToDate))
    FROM @temp Set1 
    INNER JOIN @temp List1 ON Set1.FromDate <= List1.ToDate
    AND NOT EXISTS(SELECT * FROM @temp List2 

    WHERE List1.ToDate >= List2.FromDate AND List1.ToDate < List2.ToDate) 
    WHERE NOT EXISTS(SELECT * FROM @temp Set2 
    WHERE Set1.FromDate > Set2.FromDate AND Set1.FromDate <= Set2.ToDate) 

    GROUP BY Set1.FromDate 
    ORDER BY Set1.FromDate 
选择Set1.FromDate,MIN(List1.ToDate)作为ToDate,DATEDIFF(MONTH,Set1.FromDate,MIN(List1.ToDate))
从@temp Set1开始
Set1.FromDate=List2.FromDate和List1.ToDateSet2.FromDate和Set1.FromDate您可以尝试以下代码:

DECLARE @temp TABLE (ID INT, FromDate DATETIME, ToDate DATETIME)
INSERT INTO @temp (ID, FromDate, ToDate)
VALUES   ( 1 , '2003-1-08 06:55:56' , '2005-5-08 06:55:56'),
         ( 2 , '2000-10-08 06:55:56' , '2008-7-08 06:55:56'),
         ( 3 , '2013-6-08 06:55:56' , '2015-1-08 06:55:56'),
         ( 4 , '2006-4-08 06:55:56' , '2011-3-08 06:55:56' )
SELECT 
    ID,
    CONVERT(DATE, FromDate) AS FromDate,
    CONVERT(DATE, ToDate) AS ToDate,
    DATEDIFF(MONTH, FromDate, ToDate) AS [Difference IN Months]
INTO #tmp
FROM @temp

SELECT T1.ID AS ID1, T2.ID AS ID2, T2.ToDate, T1.[Difference IN Months] + T2.[Difference IN Months] AS [Difference IN Months]
INTO #tmp2
FROM #tmp T1
INNER JOIN #tmp T2
    ON CAST(T1.ToDate AS DATE) = CAST(T2.FromDate AS DATE)
        OR (YEAR(T1.ToDate) = YEAR(T2.FromDate) AND CAST(T1.ToDate AS DATE) < CAST(T2.FromDate AS DATE))
        OR YEAR(T1.ToDate) = YEAR(T2.FromDate) - 1
DELETE #tmp WHERE ID IN (SELECT ID2 FROM #tmp2)
UPDATE #tmp
SET ToDate = (SELECT ToDate FROM #tmp2 WHERE #tmp.ID = ID1),
    [Difference IN Months] = (SELECT [Difference IN Months] FROM #tmp2 WHERE #tmp.ID = ID1)
WHERE ID IN (SELECT ID1 FROM #tmp2)

SELECT
    *,
    ROW_NUMBER() OVER(ORDER BY FromDate) AS RF
INTO #tmp3
FROM #tmp

SELECT T1.ID AS ID1, T2.ID AS ID2, T1.ToDate
INTO #tmp4
FROM #tmp3 T1
    INNER JOIN #tmp3 T2 ON T1.RF = T2.RF + 1
WHERE CAST(T1.FromDate AS DATE) < CAST(T2.ToDate AS DATE)

UPDATE #tmp
SET ToDate = (SELECT ToDate FROM #tmp4 WHERE #tmp.ID = ID2)
WHERE ID IN (SELECT ID2 FROM #tmp4)
DELETE #tmp WHERE ID IN (SELECT ID1 FROM #tmp4)

UPDATE #tmp
SET[Difference IN Months] = DATEDIFF(MONTH, FromDate, ToDate)

SELECT
    ROW_NUMBER() OVER(ORDER BY FromDate) AS ID,
    FromDate, ToDate, [Difference IN Months]
FROM #tmp

DROP TABLE #tmp
DROP TABLE #tmp2
DROP TABLE #tmp3
DROP TABLE #tmp4

每天的部分总是8吗?所以你从来没有需要考虑的部分月份吗?你尝试过DATEDIFF函数吗?SQL Server的版本是什么?SQL Server 2012,但这并不重要。这正是我想要的,谢谢
DECLARE @temp TABLE (ID INT, FromDate DATETIME, ToDate DATETIME)
INSERT INTO @temp (ID, FromDate, ToDate)
VALUES   ( 1 , '2003-1-08 06:55:56' , '2005-5-08 06:55:56'),
         ( 2 , '2000-10-08 06:55:56' , '2008-7-08 06:55:56'),
         ( 3 , '2013-6-08 06:55:56' , '2015-1-08 06:55:56'),
         ( 4 , '2006-4-08 06:55:56' , '2011-3-08 06:55:56' )
SELECT 
    ID,
    CONVERT(DATE, FromDate) AS FromDate,
    CONVERT(DATE, ToDate) AS ToDate,
    DATEDIFF(MONTH, FromDate, ToDate) AS [Difference IN Months]
INTO #tmp
FROM @temp

SELECT T1.ID AS ID1, T2.ID AS ID2, T2.ToDate, T1.[Difference IN Months] + T2.[Difference IN Months] AS [Difference IN Months]
INTO #tmp2
FROM #tmp T1
INNER JOIN #tmp T2
    ON CAST(T1.ToDate AS DATE) = CAST(T2.FromDate AS DATE)
        OR (YEAR(T1.ToDate) = YEAR(T2.FromDate) AND CAST(T1.ToDate AS DATE) < CAST(T2.FromDate AS DATE))
        OR YEAR(T1.ToDate) = YEAR(T2.FromDate) - 1
DELETE #tmp WHERE ID IN (SELECT ID2 FROM #tmp2)
UPDATE #tmp
SET ToDate = (SELECT ToDate FROM #tmp2 WHERE #tmp.ID = ID1),
    [Difference IN Months] = (SELECT [Difference IN Months] FROM #tmp2 WHERE #tmp.ID = ID1)
WHERE ID IN (SELECT ID1 FROM #tmp2)

SELECT
    *,
    ROW_NUMBER() OVER(ORDER BY FromDate) AS RF
INTO #tmp3
FROM #tmp

SELECT T1.ID AS ID1, T2.ID AS ID2, T1.ToDate
INTO #tmp4
FROM #tmp3 T1
    INNER JOIN #tmp3 T2 ON T1.RF = T2.RF + 1
WHERE CAST(T1.FromDate AS DATE) < CAST(T2.ToDate AS DATE)

UPDATE #tmp
SET ToDate = (SELECT ToDate FROM #tmp4 WHERE #tmp.ID = ID2)
WHERE ID IN (SELECT ID2 FROM #tmp4)
DELETE #tmp WHERE ID IN (SELECT ID1 FROM #tmp4)

UPDATE #tmp
SET[Difference IN Months] = DATEDIFF(MONTH, FromDate, ToDate)

SELECT
    ROW_NUMBER() OVER(ORDER BY FromDate) AS ID,
    FromDate, ToDate, [Difference IN Months]
FROM #tmp

DROP TABLE #tmp
DROP TABLE #tmp2
DROP TABLE #tmp3
DROP TABLE #tmp4
ID  FromDate    ToDate       Difference IN Months
===================================================    
1   2000-10-08  2011-03-08    125
2   2013-06-08  2015-01-08    19