与昨天的SQL服务器相比,分组尾随7天

时间:2018-03-09 14:09:36

标签: sql sql-server

我在$json = '{"1":{"show":true},"2":{"show":false}}'; echo '<pre>',print_r(json_decode($json, true)),'</pre>';exit; 中有一个example schema。缩写形式如下:

SQL server

我希望得到以下内容,假设今天为date group value 2017-01-01 a 10.00 . . 2017-01-08 a 15.00 2017-01-01 b 10.00 . . 2017-01-08 b 15.00 2017-01-01 c 10.00 . . 2017-01-08 c 15.00 2017-01-08 = difference - yesterday

trail_7

在上文中,yesterday group trail_7 yesterday difference 2017-01-07 a 10.71 15.00 4.29 2017-01-07 b 10.71 15.00 4.29 2017-01-07 c 10.71 15.00 4.29 = trail_7又称六个10和一个15

解决方案1 ​​

以下是小提琴中的例子

average(values of the last 7 days)

解决方案2

Declare @ReportDate date
set @ReportDate = '2017-01-08'

SELECT DATEADD(DAY, -1, @ReportDate) AS yesterday,
       [group],
       AVG(e.[value]) AS Trail_7,
       y.[value] AS yesterday, --I don't recommend having 2 columsn with the same name
       y.[value] - AVG(e.[value]) AS difference
FROM example e
     CROSS APPLY (SELECT sq.[value]
                  FROM example sq
                  WHERE sq.[group] = e.[group]
                    AND sq.days_date = DATEADD(DAY, -1,@ReportDate)) y
WHERE e.[days_date] >= DATEADD(DAY, -7, @ReportDate)
  AND e.[days_date] < DATEADD(DAY, 0, @ReportDate)
GROUP BY e.[group], y.[value];

4 个答案:

答案 0 :(得分:2)

假设表格中没有遗漏日期,您可以使用AVGLAG窗口函数。

select t.*,yesterday-trail_7
from (select [Date],[Group]
      ,lag(value) over(partition by [Group] order by [Date]) as yesterday
      ,avg(value) over(partition by [Group] order by [Date] rows between 7 preceding and 1 preceding) as trail_7
      from tbl
     ) t

答案 1 :(得分:0)

这是我的答案:

declare @t table (dte date,grp varchar(10),val decimal(18,2))
insert into @t
values
    (   '1/1/2017'  ,   'a' ,   10  )
,   (   '1/2/2017'  ,   'a' ,   10  )
,   (   '1/3/2017'  ,   'a' ,   10  )
,   (   '1/4/2017'  ,   'a' ,   10  )
,   (   '1/5/2017'  ,   'a' ,   10  )
,   (   '1/6/2017'  ,   'a' ,   10  )
,   (   '1/7/2017'  ,   'a' ,   10  )
,   (   '1/8/2017'  ,   'a' ,   15  )
,   (   '1/9/2017'  ,   'a' ,   15  )


declare @today date = '1/9/2017'
declare @yest date = dateadd(d,-1,@today)
declare @start date = dateadd(d,-7,@yest)

;with cte as --easier to do math on diff
(
select grp
    ,yesterday=@yest
    ,trail7 = (select avg(val) from @t tsub where dte between @start and @yest and tsub.grp=t.grp)
    ,yestVal = (select val from @t tsub where dte = @yest and tsub.grp=t.grp)
from @t t
where dte=@today
)

select cte.*
    , differnce=yestVal-trail7
from cte

答案 2 :(得分:0)

这有点猜测,因为根据提供的示例数据,我不知道您如何获得10的值trail_7

DECLARE @ReportDate date = '20170108';

SELECT DATEADD(DAY, -1, @ReportDate) AS yesterday,
       [group],
       AVG(e.[value]) AS Trail_7,
       y.[value] AS yesterday, --I don't recommend having 2 columsn with the same name
       y.[value] - AVG(e.[value]) AS difference
FROM example e
     CROSS APPLY (SELECT sq.[value]
                  FROM example sq
                  WHERE sq.[group] = e.[group]
                    AND sq.days_date = DATEADD(DAY, -1,@ReportDate)) y
WHERE e.[days_date] >= DATEADD(DAY, -7, @ReportDate)
  AND e.[days_date] < DATEADD(DAY, 0, @ReportDate)
GROUP BY e.[group], y.[value];

如果你能更好地解释,那将非常有帮助。

答案 3 :(得分:0)

我认为这就是你所追求的:

select cast((getutcdate()-1) as date) yesterday
, [group]
, [trail_7]
, [trail_1] --aka yesterday, but we used than name above
, [trail_1] - [trail_7] [difference]
FROM
(
    SELECT [group]
    , avg(case 
        when [days_date] = cast((getutcdate()-1) as date) then [value] 
        else null --null is not counted in the average
    end) [trail_1]
    , avg([value]) [trail_7]
    FROM example
    WHERE [days_date] >= cast(getutcdate()-7 as date)
    group by [group]
) x
order by [group]

SQL小提琴:http://sqlfiddle.com/#!18/dd89c/1