获取聚合日期统计/数据透视的最快方法

时间:2014-03-28 13:57:45

标签: sql-server sql-server-2008 tsql report

我试着写一些必须是相当普遍的审计报告;随时间推移添加到表中的行数;报告了以前的周期,以了解数据的趋势。

我有一个表来审核数据库中行的创建。它有一个字段RowEnteredDate日期时间。我希望创建一个周/月/当前季/年的审计报告。

在我的脑海中,我正在看这个日期周围的数据多次传递;这在我的数据库中相当昂贵。我此刻的推理是

我开始计算我的年/月/季度的日期

set datefirst 1

declare @dateranges table (
    rangelabel varchar(100), 
    startdate datetime, 
    enddate datetime, 
    myrowcount integer identity(1,1) 
    )


insert into @dateranges (Rangelabel, startdate, enddate)
select 
    'Current Year', 
    DATEADD(yy, DATEDIFF(yy,0,GETDATE()), 0),
    DATEADD(ms,-3,DATEADD(yy, DATEDIFF(yy,0,GETDATE()  )+1, 0))


    insert into @dateranges (Rangelabel, startdate, enddate)
select 
    'Current Quarter', 
    DATEADD(qq, DATEDIFF(qq,0,GETDATE()), 0),
    DATEADD(qq, DATEDIFF(qq, - 1, getdate()), - 1)


insert into @dateranges (Rangelabel, startdate, enddate)
select 
    'Current Month', 
    DATEADD(month, DATEDIFF(month, 0, getdate()), 0),
    DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))

如果我的表是tblOfUsefullFacts并且我的日期行是RowEnteredDate,那么获取聚合的最佳方法是什么?被白天打破。

Date Range    Mon    Tues     Wed     Thu    Fri    Sat    Sun 
Year To date  12000  13000    12000   3200   98000  8900   4000 
Quarter 1        302    407      201     97     1732   120     37 
Month ...

我可以使用像这样的查询轻松地获得白天的总数

select
    count(*) ,
    datepart(weekday, RowEnteredDate)
    from 
        tblOfUsefullFacts aa
    Where 
        datepart(weekday, RowEnteredDate) is not null
    group by datepart(weekday, RowEnteredDate)
    order by datepart(weekday, RowEnteredDate) sac

这逐行选择数据;我可以转动和循环以获取数据。我有点紧张,因为真实的数字在它们中的数百万,并且如果我可以避免,它不希望影响基础处理。

因为我需要在多次传递中执行此操作,所以有一种更轻松的方法来执行此操作而无需运行循环来获取总数吗?或者我的模糊大脑忽略了SQL中的一种机制。

1 个答案:

答案 0 :(得分:1)

这应该会让你知道如何做到这一点。很抱歉任何语法错误,都没有经过测试。

   ;with cte as 
    (
        select
            d.rangelabel,
            datepart(weekday, RowEnteredDate) as WkDay,
            count(*) as RowCt
        from tblOfUsefullFacts f
        join @dateranges d on f.RowEnteredDate between d.startdate and d.enddate
        Where datepart(weekday, RowEnteredDate) is not null
        group by  d.rangelabel,datepart(weekday, RowEnteredDate)
    )
    select
        RangeLabel,
        sum(case when WkDay = 1 then RowCt else 0 end) as Sunday,
        sum(case when WkDay = 2 then RowCt else 0 end) as Monday,
        sum(case when WkDay = 3 then RowCt else 0 end) as Tuesday,
        sum(case when WkDay = 4 then RowCt else 0 end) as Wednesday,
        sum(case when WkDay = 5 then RowCt else 0 end) as Thursday,
        sum(case when WkDay = 6 then RowCt else 0 end) as Friday,
        sum(case when WkDay = 7 then RowCt else 0 end) as Saturday
    from cte
    group by RangeLabel