[英]Year over Year by Month Comparison and Month to Date in BigQuery
Edit: @shawnt00 has the correct answer.编辑:@shawnt00 有正确答案。 Thank you very much!
非常感谢!
I am having trouble accurately doing a year over year comparison by month but at any point during the month.我无法准确地按月进行逐年比较,但在本月的任何时候。 For example for August 2022 vs 2021, I want to compare August 1 - August 25, rather than full month of August 2021.
例如,对于 2022 年 8 月与 2021 年,我想比较 8 月 1 日至 8 月 25 日,而不是 2021 年 8 月的整个月份。
I am also using a daily date field.我也在使用每日日期字段。
I want the final result to basically be:我希望最终结果基本上是:
Product_ID, Year, Month, PY_Sales, CY_Sales Product_ID、年、月、PY_Sales、CY_Sales
Edit: I have daily totals.编辑:我有每天的总数。 Some products do have not sales on certain days though:
有些产品在某些日子没有销售:
product_id ![]() |
sale_date![]() |
units![]() |
---|---|---|
1 ![]() |
2021-01-01 ![]() |
5 ![]() |
2 ![]() |
2021-01-02 ![]() |
4 ![]() |
... ![]() |
... ![]() |
... ![]() |
1 ![]() |
2021-06-05 ![]() |
2 ![]() |
2 ![]() |
2022-01-06 ![]() |
1 ![]() |
2 ![]() |
2022-08-15 ![]() |
9 ![]() |
This is the code I have, but it doesn't do MTD.这是我拥有的代码,但它不执行 MTD。 So 2021 August is the entire month of August and I want it the same dates for 2022. I used this code because some products do not have sales on certain months.
所以 2021 年 8 月是整个 8 月,我希望它与 2022 年的日期相同。我使用此代码是因为某些产品在某些月份没有销售。
WITH cte AS
(
SELECT
PRODUCT_ID,
EXTRACT(YEAR FROM SALE_DATE) AS Year,
EXTRACT(MONTH FROM SALE_DATE) AS Month,
CONCAT(EXTRACT(YEAR FROM SALE_DATE), '-',EXTRACT(MONTH FROM SALE_DATE)) AS Year_Month,
SUM(Units) AS Units
FROM data
WHERE Product_ID = 1
AND DATE(SALE_DATE) >= '2019-01-01'
GROUP BY 1, 2, 3
),
diff AS
(
SELECT
COALESCE(c.PRODUCT_ID, p.PRODUCT_ID) AS Product_ID,
COALESCE(c.Year, p.Year + 1) AS Year,
COALESCE(c.Month, p.Month) AS Month,
IFNULL(c.Units, 0) AS Current_Units,
IFNULL(p.Units, 0) AS Previous_Units,
NULLIF(((IFNULL(c.Units, 0) - IFNULL(p.Units,0)) / p.Units),0) * 100 AS Percent_Change
FROM CTE c
FULL OUTER JOIN CTE p ON c.PRODUCT_ID = p.PRODUCT_ID AND c.Year = p.Year + 1 AND c.Month = p.Month
WHERE c.Year <= EXTRACT(YEAR FROM CURRENT_DATE())
ORDER BY 2, c.Year, c.Month
)
SELECT *
FROM diff
--This is to avoid dividing by 0
WHERE diff.Previous_Units > 0
--AND Percent_Change <= -.5
You could just roll up two different monthly totals and then switch for the current month comparison:您可以汇总两个不同的每月总计,然后切换到当前月份的比较:
with agg as (
select
PRODUCT_ID,
extract(year from SALE_DATE) as yr,
extract(month from SALE_DATE) as mth,
sum(Units) as Units,
sum(case when extract(day from SALE_DATE) <= extract(day from current_date())
then Units end) as UnitsMTD
from data
where date(SALE_DATE) >= '2019-01-01' -- one year before report output
group by 1, 2, 3
)
select c.Yr, c.Mth, c.PRODUCT_ID,
case when Yr = extract(year from current_date())
and Mth = extract(month from current_date())
then (c.UnitsMTD - p.UnitsMTD) / p.UnitsMTD
else (c.Units - p.Units ) / p.Units
end as Percent_Change
from agg c left outer join agg p
on p.Product_ID = c.Product_ID and p.Yr = c.Yr - 1 and p.Mth = c.Mth
order by c.Yr, c.Mth, c.PRODUCT_ID;
Note my earlier comment about leap years.请注意我之前关于闰年的评论。 This will treat February 28 of the year following a leap year as an "MTD" month.
这会将闰年之后的次年 2 月 28 日视为“MTD”月份。 You might need to handle that differently inside the
case
expression.您可能需要在
case
表达式中以不同方式处理它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.