سؤال

I am tryig to write what must be a fairly common audit report; number of rows added to a table over time; reported back against previous cycles to understand the trends in the data.

I have a table that audits creation of rows in the database. It has a field RowEnteredDate date time. I am looking to create an audit report Week/ Month/ Current Quarter / Year.

In my head I am looking at this as multiple passes over the data around the dates; which is quite costly in my database. My reasoning at the moment is

I started out with working out the dates for my year / month / quarter

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))

If my table is tblOfUsefullFacts and my date row is RowEnteredDate what is the best way to get the aggregate; broken by Day.

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 ...

I can get the totals by day easily enough using a query like this

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

This selects the data out row by row; which i could pivot and loop round to get the data. Im slightly nervous as the real numbers are in the 10's of millions in them and would like to not impact the underlying processing if i can avoid it.

As i need to do this in multiple passes is there a lighter way to do this without running the loops to get the totals? Or a mechanism in SQL my fuzzy brain is ignoring.

هل كانت مفيدة؟

المحلول

This should give you an idea how to do it. Sorry for any syntax errors, it isn't tested.

   ;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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top