简体   繁体   中英

Automated year average cost for following years

I'd like to get some help with a code, I want to get the average Price per City and per Year from TableA that holds data from the last three years.

 TableA

 Date       City    Price
 10/23/2018 Leon    1088
 2/27/2018  NewYork 1312
 4/19/2017  Texas   1303
 4/19/2017  London  1303
 4/19/2019  NewYork 1303
 2/12/2018  Leon    1251
 4/7/2017   Leon    1170
 3/20/2019  London  1650
 12/18/2017 Texas   1358
 2/18/2019  Leon    1088
 7/3/2017   NewYork 1391
 8/8/2019   Texas   830
 4/5/2018   London  1869.5
 1/29/2018  London  1169
 8/9/2019   Texas   1130

Average price should be calculated per city per year. Results should be grouped by year and shown per each City as follows:

Result from TableA

City       Avg2017    Avg2018    Avg2019
Leon        1170      1169.5     1088
London      1303      1519.25    1650
New York    1391      1312       1303
Texas       1330.5     0         1390

However I want it to automatically process future data and that when 2020 comes then 2017 disappears from the results (and so on for further years).

The scenario would be something like:

 TableB

 Date       City    Price
 10/23/2018 Leon    1088
 2/27/2018  NewYork 1312
 4/19/2020  Texas   1303
 4/19/2020  London  1303
 4/19/2019  NewYork 1303
 2/12/2018  Leon    1251
 4/7/2020   Leon    1170
 3/20/2019  London  1650
 12/18/2020 Texas   1358
 2/18/2019  Leon    1088
 7/3/2020   NewYork 1391
 8/8/2019   Texas   830
 4/5/2018   London  1869.5
 1/29/2018  London  1169
 8/9/2019   Texas   1130
 4/19/2017  Texas   1303
 4/19/2017  London  1303
 4/7/2017   Leon    1170
 12/18/2017 Texas   1358
 7/3/2017   NewYork 1391

And the result without 2017 and with 2020.

Result from TableB

City          Avg2018    Avg2019  Avg2020
Leon          1169.5     1088     1170
London        1519.25    1650     1303
New York      1312       1303     1391
Texas         0          1390     1330.5

My SQL Server version is 15.0.18142

Is this possible?

For dynamic year pivoting , our only option is to use dynamic queries.

getting the last 3 years of data

between dateadd(yy, -3, getdate()) and getdate()

full query:

select * into #res from (
    select '10/23/2018' as d ,'Leon' City, 1088 as price
    union all
    select '2/27/2018' ,'NewYork' ,1312
    union all
    select '4/19/2017' ,'Texas' ,1303
    union all
    select '4/19/2017' ,'Leon' ,1303
    union all
    select '4/19/2019' ,'London' ,1303
    union all
    select '4/19/2019' ,'NewYork' ,2000
    union all
    select '3/19/2019' ,'NewYork' ,1000
    union all
    select '3/19/2020' ,'NewYork' ,1000
    union all
    select '3/19/2020' ,'London' ,3000
    union all
    select '3/19/2020' ,'Texas' ,1000
)res


declare  @cols nvarchar(max);
declare  @sql nvarchar(max);

select @cols =
    stuff((select N'],[Avg' + d
       from (select distinct right(d, 4) as d
          from #res where right(d, 4) between year(getdate())-1 and year(getdate())+1) AS t1   
       for xml path('')
    ), 1, 2, '') + N']';

set @sql = N'Select City, ' + @cols + N'
            from (select City, concat(''Avg'', right(d, 4)) as d, price from #res)t1 
            pivot 
            (
                avg(t1.price)
                for t1.d in (' + @cols + N')
            ) p         
            '
print @sql;
exec sp_executesql @sql;

drop table #res

You can do conditional aggregation:

select 
    city,
    avg(case when [date] >= date('2017-01-01') and [date] < date('2018-01-01') then price end) avg2017,
    avg(case when [date] >= date('2018-01-01') and [date] < date('2019-01-01') then price end) avg2018,
    avg(case when [date] >= date('2019-01-01') and [date] < date('2020-01-01') then price end) avg2019
from mytable
where [date] >= date('2017-01-01') and [date] <= date('2020-01-01)
group by city

I would recommend using date intervals instead of using year() to define the year each date belongs to, since this will benefit an existing index on date (while function year() will not).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM