在SQL Server中减去行

时间:2016-04-26 05:09:17

标签: sql sql-server

我有这样的数据集:

ID       | IssueDate               
194924   | 2013-07-31 00:00:00.000 
194924   | 2010-06-15 00:00:00.000  
194924   | 2012-07-30 00:00:00.000   
194924   | 2012-12-11 00:00:00.000    
194924   | 2014-08-04 00:00:00.000    
194966   | 2012-06-02 00:00:00.000 
194966   | 2011-02-03 00:00:00.000 
194966   | 2011-02-01 00:00:00.000 
194987   | 2013-04-25 00:00:00.000 
194987   | 2010-12-03 00:00:00.000 

我想首先使用ID和IssueDate对数据进行排序,然后减去连续两行的IssueDates(以查找一行和下一行之间的时间),然后计算每个唯一ID的最大值,最小值和平均值。

2 个答案:

答案 0 :(得分:1)

如果您的Sql Server版本是2014,则下面的版本可能对您有帮助。

您案例的架构:

    CREATE TABLE #TAB (
        ID BIGINT
        ,IssuDate DATETIME
        )

    INSERT INTO #TAB
    SELECT 194924
        ,'2013-07-31 00:00:00.000'
        UNION ALL
    SELECT 194924
        ,'2010-06-15 00:00:00.000'
        UNION ALL
    SELECT 194924
        ,'2012-07-30 00:00:00.000'
        UNION ALL
    SELECT 194924
        ,'2012-12-11 00:00:00.000'
        UNION ALL
    SELECT 194924
        ,'2014-08-04 00:00:00.000'
        UNION ALL
    SELECT 194966
        ,'2012-06-02 00:00:00.000'
        UNION ALL
    SELECT 194966
        ,'2011-02-03 00:00:00.000'
        UNION ALL
    SELECT 194966
        ,'2011-02-01 00:00:00.000'
        UNION ALL
    SELECT 194987
        ,'2013-04-25 00:00:00.000'
        UNION ALL
    SELECT 194987
        ,'2010-12-03 00:00:00.000'

排序并找到时差后的结果:

    SELECT *, DATEDIFF(DD, ISNULL(LAG(ISSUDATE)  OVER(PARTITION BY ID ORDER BY ID,IssuDate ), IssuDate),IssuDate) AS TIME_DIFF_IN_DAYS  
    FROM #TAB

用于聚合最小值Max&平均

    SELECT ID, MIN(TIME_DIFF_IN_DAYS) AS MIN_TIME_TAKEN, MAX(TIME_DIFF_IN_DAYS) MAX_TIME_TAKEN, AVG(TIME_DIFF_IN_DAYS) AVG_TIME_TAKEN FROM (
    SELECT *, DATEDIFF(DD, ISNULL(LAG(ISSUDATE)  OVER(PARTITION BY ID ORDER BY ID,IssuDate ), IssuDate),IssuDate) AS TIME_DIFF_IN_DAYS  FROM #TAB
    )AS A
    WHERE TIME_DIFF_IN_DAYS>0  --This one you can comment if you want to show 0 diffence in time
    GROUP BY ID

答案 1 :(得分:0)

我不确定"和c1.id = c.id"在CTE1中,我不确定您的具体要求。毫无疑问,你可以尝试一些类似的东西,

declare @t table(ID int,IssuDate datetime)
insert into @t values          
(194924,'2013-07-31 00:00:00.000') 
,(194924,'2010-06-15 00:00:00.000')  
,(194924,'2012-07-30 00:00:00.000')   
,(194924,'2012-12-11 00:00:00.000')    
,(194924,'2014-08-04 00:00:00.000')    
,(194966,'2012-06-02 00:00:00.000') 
,(194966,'2011-02-03 00:00:00.000') 
,(194966,'2011-02-01 00:00:00.000') 
,(194987,'2013-04-25 00:00:00.000') 
,(194987,'2010-12-03 00:00:00.000') 

;with CTE as
(select *,ROW_NUMBER()over(order by id,IssuDate)rn
from @t 
)
,Cte1 as
(
select * 
,(select datediff(second,c.IssuDate,c1.IssuDate) from CTE c1 where c1.rn=c.rn+1 and c1.id=c.id)Time_between
from CTE C
)

select sum(Time_between),min(Time_between),avg(Time_between),max(Time_between) from cte1 
group by id