带标签的增量SQL

时间:2015-07-03 19:25:18

标签: sql sql-server sql-server-2008

我正在尝试从SQL Server 2008 R2中的单个表中提取...我有两列。

IDate[Datetime] and ID[Numeric]

我正在尝试构建一个返回以下内容的MSSQL查询。

可搜索标准

 -IDate MM\DD\YYYY
 -ID ####

返回

-HourIncrement 00:00 - 00:30
-RecordsForHour 3
-CumulativeRecords 3
-ID

-HourIncrement 00:30 - 01:00
-RecordsForHour 1
-CumulativeRecords 4
-ID

示例数据

enter image description here

预期结果

enter image description here

2 个答案:

答案 0 :(得分:0)

这可能对您有所帮助: -

Set Nocount On;

Declare @MinTime Time

Select   @MinTime = '00:00'

Declare  @test Table
(
     IDate      Datetime
    ,ID         Int
)

Declare @resultTable Table
(
     RowId              Int Identity(1,1) Primary Key
    ,RecordsPerHour     Int
    ,ID                 Int
    ,MinTime            Time
    ,MaxTime            Time
)

Insert Into @test(IDate,ID) Values
 ('2015-06-23 00:11:22.387',1000)
,('2015-06-23 00:15:52.192',1000)
,('2015-06-23 00:19:29.344',1000)
,('2015-06-23 00:39:20.660',1000)

;With timeCte As
(
    Select   @MinTime As minTime
            ,Dateadd(Mi, 30, @MinTime) As maxTime

    Union All

    Select   Dateadd(mi, 30, minTime) As minTime
            ,Case When t.maxTime = Cast('23:00' As Time) Then Dateadd(mi, 29, maxTime) Else Dateadd(mi, 30, maxTime) End As maxTime
    From    timeCte As t
    Where   t.maxTime < Cast('23:59' As Time)
)


Insert Into @resultTable(RecordsPerHour,ID,MinTime,MaxTime)
Select   Count(1) As RecordsForHour
        ,t.ID
        ,tc.minTime
        ,tc.maxTime
From    timeCte As tc With (Nolock)
        Join @test As t On Cast(t.IDate As Time) >= tc.minTime
            And Cast(t.IDate As Time) <= tc.maxTime
Group By t.ID
        ,tc.minTime
        ,tc.maxTime

Select   Cast(t.minTime As Varchar(5)) + ' - ' + Cast(t.maxTime As Varchar(5)) As Time
        ,t.RecordsPerHour
        ,t.RecordsPerHour + Isnull(t1.RecordsPerHour,0) As CumulativeRecords
        ,t.ID
From    @resultTable As t
        Left Join @resultTable As t1 On t.ID = t1.ID And t.RowId = (t1.RowId + 1)
Order By t.ID
        ,t.MinTime
        ,t.MaxTime

如果您使用的是MSSQL Server 2012或更高版本,则可以使用Lag()函数代替左连接来计算CumulativeRecords。

上述查询的

输出: -

enter image description here

答案 1 :(得分:0)

这将提供所需的结果,而不使用CTE(公用表表达式),这可能更容易理解并且可能具有更好的性能。

定义样本测试数据:

Declare  @test Table
(
     IDate      Datetime
    ,ID         Int
)

Insert Into @test(IDate,ID) Values
 ('2015-06-23 00:11:22.387',1000)
,('2015-06-23 00:15:52.192',1000)
,('2015-06-23 00:19:29.344',1000)
,('2015-06-23 00:39:20.660',1000)

,('2015-06-23 01:21:22.387',1000)
,('2015-06-23 01:25:52.192',1000)
,('2015-06-23 01:32:29.344',1000)
,('2015-06-23 01:39:20.660',1000)

,('2015-06-23 23:21:22.387',1000)
,('2015-06-23 23:25:52.192',1000)
,('2015-06-23 23:32:29.344',1000)
,('2015-06-23 23:39:20.660',1000)

,('2015-06-24 00:11:22.387',1000)
,('2015-06-24 00:15:52.192',1000)
,('2015-06-24 00:19:29.344',1000)
,('2015-06-24 00:39:20.660',1000)

查询:

select *
from
(
    select Convert(varchar, DayPeriod, 101) as DayPeriod,
    HourIncrement,
    count(*) as RecordForHour,
    max(rownum) as CumulativeRecords,
    min(ID) as ID
    from
    (
        select *, 
            Row_Number() over (order by IDate asc) as rownum,       
            DATEADD(dd, 0, DATEDIFF(dd, 0, IDate)) as DayPeriod,
            case when DATEPART(mi, IDate) between 0 and 30
            then dateHour + ':00 - ' + dateHour + ':30'
            else dateHour + ':30 - ' + dateNextHour + ':00'
            end as HourIncrement
        from 
            (
                select *,
                right('00' + Convert(varchar(4), DATEPART(hh, IDate)), 2) as dateHour,
                right('00' + Convert(varchar(4), DATEPART(hh, DateAdd(hh, 1, IDate))), 2) as dateNextHour
                from @test
            ) t1
    ) t2
    group by DayPeriod, HourIncrement
) t3
order by CumulativeRecords asc

结果

enter image description here