ecc/UpdateStockMonthlySnapshots.sql (291 lines of code) (raw):
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Update (refresh) stock monthly snapshots table for records between provided dates (inclusive).
#
# `monthly_inventory_aggregation` table must be up to date before calling this function.
#
# @param start_date Starting date of refresh. Must be the first day of a month.
# @param end_date Ending date of refresh. Must be later than start_date.
CREATE OR REPLACE PROCEDURE
`{{ project_id_tgt }}.{{ dataset_reporting_tgt }}.UpdateStockMonthlySnapshots` (
start_date DATE,
end_date DATE
)
OPTIONS (description = "This procedure updates the 'stock_monthly_snapshots' table by passing the parameters 'start_date' and 'end_date'.")
BEGIN
CREATE TEMP TABLE LastMonthSnapshot AS
SELECT
*
EXCEPT (
month_end_date,
cal_year,
cal_month
),
LAST_DAY(start_date, MONTH) AS month_end_date,
EXTRACT(YEAR FROM start_date) AS cal_year,
EXTRACT(MONTH FROM start_date) AS cal_month
FROM
`{{ project_id_tgt }}.{{ dataset_reporting_tgt }}.stock_monthly_snapshots`
WHERE
month_end_date = DATE_SUB(start_date, INTERVAL 1 DAY);
CREATE TEMP TABLE CurrentPeriodMovements AS
SELECT *
FROM
`{{ project_id_tgt }}.{{ dataset_reporting_tgt }}.monthly_inventory_aggregation`
WHERE
month_end_date BETWEEN start_date AND end_date;
CREATE TEMP TABLE AllMaterialCombinations AS
SELECT DISTINCT *
FROM (
SELECT
mandt,
werks,
matnr,
charg,
lgort,
bukrs,
bwart,
insmk,
sobkz,
shkzg,
meins,
waers
FROM
LastMonthSnapshot
UNION ALL
SELECT
mandt,
werks,
matnr,
charg,
lgort,
bukrs,
bwart,
insmk,
sobkz,
shkzg,
meins,
waers
FROM
CurrentPeriodMovements
);
DELETE
FROM
`{{ project_id_tgt }}.{{ dataset_reporting_tgt }}.stock_monthly_snapshots`
WHERE
month_end_date BETWEEN start_date AND end_date;
INSERT INTO
`{{ project_id_tgt }}.{{ dataset_reporting_tgt }}.stock_monthly_snapshots`
(
mandt, werks, matnr, charg, lgort, bukrs, bwart, insmk, sobkz,
shkzg, cal_year, cal_month, meins,
waers, month_end_date,
total_monthly_movement_quantity,
total_monthly_movement_amount,
amount_monthly_cumulative,
quantity_monthly_cumulative
)
WITH
DateDim AS (
SELECT DISTINCT
calyear AS cal_year,
calmonth AS cal_month,
monthenddate AS month_end_date
FROM
`{{ project_id_src }}.{{ k9_datasets_processing }}.calendar_date_dim`
WHERE
date BETWEEN start_date AND end_date
),
MonthlyCumulativeRaw AS (
SELECT
month_end_date,
cal_year,
cal_month,
mandt,
werks,
matnr,
charg,
lgort,
bukrs,
bwart,
insmk,
sobkz,
shkzg,
meins,
waers,
total_monthly_movement_amount, -- noqa: RF02
total_monthly_movement_quantity -- noqa: RF02
-- this ensures all month / material combinations exist even if
-- they don’t exist in current movements
FROM
DateDim
CROSS JOIN
AllMaterialCombinations
LEFT JOIN
CurrentPeriodMovements
USING
(
month_end_date,
cal_year,
cal_month,
mandt,
werks,
matnr,
charg,
lgort,
bukrs,
bwart,
insmk,
sobkz,
shkzg,
meins,
waers
)
UNION ALL
-- take balance of last month and treat it as beginning balance of the first month
SELECT
month_end_date,
cal_year,
cal_month,
mandt,
werks,
matnr,
charg,
lgort,
bukrs,
bwart,
insmk,
sobkz,
shkzg,
meins,
waers,
amount_monthly_cumulative AS total_monthly_movement_amount,
quantity_monthly_cumulative AS total_monthly_movement_quantity
FROM
LastMonthSnapshot
),
MonthlyCumulative AS (
SELECT
month_end_date,
cal_year,
cal_month,
mandt,
werks,
matnr,
charg,
lgort,
bukrs,
bwart,
insmk,
sobkz,
shkzg,
meins,
waers,
SUM(total_monthly_movement_quantity) AS total_monthly_movement_quantity_sum,
SUM(total_monthly_movement_amount) AS total_monthly_movement_amount_sum
FROM
MonthlyCumulativeRaw
GROUP BY
month_end_date,
cal_year,
cal_month,
mandt,
werks,
matnr,
charg,
lgort,
bukrs,
bwart,
insmk,
sobkz,
shkzg,
meins,
waers
)
SELECT
mandt,
werks,
matnr,
charg,
lgort,
bukrs,
bwart,
insmk,
sobkz,
shkzg,
cal_year,
cal_month,
meins,
waers,
month_end_date,
COALESCE(total_monthly_movement_quantity, 0) AS total_monthly_movement_quantity, -- noqa: RF02
COALESCE(total_monthly_movement_amount, 0) AS total_monthly_movement_amount, -- noqa: RF02
SUM(total_monthly_movement_amount_sum) -- noqa: RF02
OVER (
PARTITION BY
mandt,
matnr,
werks,
charg,
lgort,
bukrs,
bwart,
insmk,
sobkz,
shkzg,
meins,
waers
ORDER BY month_end_date ASC
ROWS UNBOUNDED PRECEDING
) AS amount_monthly_cumulative,
SUM(total_monthly_movement_quantity_sum) -- noqa: RF02
OVER (
PARTITION BY
mandt,
matnr,
werks,
charg,
lgort,
bukrs,
bwart,
insmk,
sobkz,
shkzg,
meins,
waers
ORDER BY month_end_date ASC
ROWS UNBOUNDED PRECEDING
) AS quantity_monthly_cumulative
FROM
MonthlyCumulative
LEFT JOIN
CurrentPeriodMovements
USING
(
month_end_date,
cal_year,
cal_month,
mandt,
werks,
matnr,
charg,
lgort,
bukrs,
bwart,
insmk,
sobkz,
shkzg,
meins,
waers
)
QUALIFY
amount_monthly_cumulative IS NOT NULL OR quantity_monthly_cumulative IS NOT NULL;
END;