【问题标题】:Cumulative time difference per group每组累计时间差
【发布时间】:2015-10-17 21:17:38
【问题描述】:

我有一个如下表结构

DECLARE @XTable TABLE 
(
  ColA Varchar(20), 
  ColB Varchar(20),
  DateCol DATE
)

INSERT INTO @XTable 
VALUES
    ('A', 'X1', '4/1/2015'), ('A', 'X2', '4/10/2015'), ('A', 'X3', '4/12/2015'),
    ('A', 'X4', '4/16/2015'), ('B', 'X1', '5/18/2015'), ('B', 'X2', '5/20/2015')

预期输出:

/*
    ColA   ColB  DateCol      Diff
    A       X1    4/1/2015    0
    A       X2    4/10/2015   9
    A       X3    4/12/2015   2
    A       X3    4/12/2015   11
    A       X4    4/16/2015   15
    A       X4    4/16/2015   5
    A       X4    4/16/2015   4
    B       X1    5/18/2015   0
    B       X2    5/20/2015   12
*/

例如: A X4 与 A X1、A X2 和 A X3 的日期不同 & A X3 与 A X1 & A X2 的日期不同

我可以通过下面的查询得到与最后一行的区别

;WITH Dataf
    AS (
    SELECT 
        *,
        ROW_NUMBER() OVER (ORDER BY  ColA,ColB, DateCol) AS RowNum
    FROM 
        @XTable
    )

    SELECT a.ColA, a.ColB, SUM(DATEDIFF(Dd,b.DateCol,a.DateCol)) as TotalTime
    FROM 
     Dataf AS A
     LEFT OUTER JOIN Dataf AS B   
                ON A.RowNum = B.RowNum + 1 and a.ColA = b.ColA
    GROUP BY a.ColA, a.ColB

想申请多个CTE,下面是我现在的工作

;WITH Dataf
AS (
SELECT 
    *,
    ROW_NUMBER() OVER (PARTITION BY ColA ORDER BY  DateCol) AS RowNum
FROM 
    @XTable
),

CTE AS 
(
   SELECT ColA, ColB, DateCol, RowNum, NULL AS DateDifference
   FROM Dataf WHERE RowNum = 1
   UNION ALL
   SELECT DF.ColA, DF.ColB, DF.DateCol, DF.RowNum ,
            DATEDIFF(DD, CT.DateCol, DF.DateCol) AS DateDifference
   FROM Dataf DF
    JOIN  CTE CT ON DF.ColA = CT.ColA AND   DF.RowNum = CT.RowNum + 1

)
SELECT * 
FROM CTE 
ORDER BY ColA

【问题讨论】:

  • 如果您使用的是 SQL Server 2012,您不能只使用 LAG() 函数吗?您仍然需要 CTE,但您不必先编号然后加入。也许我只是不理解你的算法或你在这里试图代表什么。
  • @BaconBits 感谢您的意见。是的,我可以从 LAG 获取最后一行信息,也可以对其进行 DATEDIFF,但我还需要访问比上一行更旧的行

标签: tsql sql-server-2012 common-table-expression


【解决方案1】:

您可以改为使用 LEFT OUTER JOIN 到您准备的 CTE。这是怎么做的

    ;WITH DataForm
    AS (
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY Cola ORDER BY  DateCol) AS RowNum
    FROM 
        @XTable
    )


SELECT ColA, ColB, DateCol, 0
FROM DataForm WHERE RowNum = 1
UNION
SELECT T1.ColA, T1.ColB, T1.DateCol
, DATEDIFF(dd,T2.DateCol, T1.Datecol) 
FROM DataForm T1
LEFT OUTER JOIN DataForm T2 ON T1.ColA = T2.ColA            
    AND T1.RowNum >= T2.RowNum 
WHERE DATEDIFF(dd,T2.DateCol, T1.Datecol) > 0

SQL Fiddler Example

【讨论】:

  • 非常感谢您的回答。我做了很多搜索,但无法得到它。 :)
猜你喜欢
  • 2020-08-27
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多