So, I've got one problem: getting an actual sum/avg with over, partitioning through product codes, of the last 12 months (counting the one being processed), in a scenario where there are products that may not exist in a month.
Tried to start with a TL;DR, let's go for the actual thing:
- My table has 4 fields: year, month, product code and value;
- I need sum over the last year (selected month + past 11 months);
- I need avg over the last year (same).
I tried with:
SELECT * FROM (
SELECT year, month, product,
AVG(value) OVER (
PARTITION BY product
ORDER BY year, month
ROWS 11 PRECEDING
) as average,
SUM(value) OVER (
PARTITION BY product
ORDER BY year, month
ROWS 11 PRECEDING
) as sum
FROM suchDB.muchUSER.awesomeTABLE
) q
where year = <insert year> and month = <month>
Problems:
- If any queried month doesn't have product '123', it'll ignore if the product has history on the table, it won't bring me an average or sum of past months.
- If any past month, which should be part of history of a queried month, doesn't have product '123', it'll ignore that month and move on to a month past the 'last year' scope (a queried October without a July would return it's version of the previous year, instead of stopping on November).
We used to query this thing using 'GROUP BY product'
and 'WHERE ((year-1)*100)+month > queriedYear-1Month AND (year*100)+month <= queriedYearMonth'
until someone pointed us in the OVER/PARTITION direction and we changed everything... but even then we had some problems, like avg()
function will ignore NULL months...
Help?
FORGOT ONE VERY IMPORTANT THING
The data in awesomeTABLE is versioned - each year/month can have more than one version. Only the latest must be used. I usually do this by joining with a select distinct year, month, max(version) from awesomeTABLE group by year, month
but it seems to kill some of the possible solutions...