Karim Sabaa
10/24/2024, 1:30 PMWITH last_prices AS (
SELECT product_id, price AS last_price
FROM fact_sales
WHERE (product_id, sale_date) IN (
SELECT product_id, MAX(sale_date)
FROM fact_sales
GROUP BY product_id
)
)
SELECT SUM(fs.quantity * lp.last_price) AS total_sales
FROM fact_sales fs
JOIN last_prices lp ON fs.product_id = lp.product_id;
The only way I found using GoodData was by adding product_id as rows in the table visualisation then sum all the rows of the table. But I wanted to get directly a single output number using a metric, otherwise I won't be able to visualize it correctly nor use it compose further metrics.Karim Sabaa
10/24/2024, 2:09 PMMichal Hauzírek
10/24/2024, 5:40 PMSELECT DATETIME_DIFF("2020-01-01 00:00",{label/date.minute}, MINUTE) BY {dataset/fact_sales}
the BY section here tells the system to calculate the difference in the fact sales dataset (there could be theoretically more datasets connected to the same date)
Now we can define the metric for last price for product:
_*_last_product_price=*_
SELECT MAX(
SELECT {fact/unit_price}
WHERE (
SELECT ROW_NUMBER({metric/_helper_date_minutes}) DESC WITHIN({label/product_id})
)=1
) BY {label/product_id}, ALL OTHER
here we are using the first date-based metric to rank the sales records in descending order with ROW_NUMBER function and select the one with row_numer = 1 (meaning the latest because of the DESC)
and using the BY {label/product_id}, ALL OTHER
we let the system know that it can take this result and expand/repeat it across the other attributes (but only for the same product_id).
now with this it is easy to define the final metric to multiply it by quantity and sum it up:
SELECT SUM({fact/quantity}*{metric/_last_product_price})
That should give you the calculation you asked for.
You could potentially also do everything within a single complex metric.
SELECT SUM({fact/quantity} * (
SELECT MAX(
SELECT {fact/price}
WHERE
(
SELECT ROW_NUMBER((
SELECT DATETIME_DIFF("2020-01-01 00:00", {label/sale_date.minute}, MINUTE)
BY {dataset/fact_sales}))
DESC
WITHIN({label/product_id})) = 1)
BY {label/product_id}, ALL OTHER))
I hope this helps.Michal Hauzírek
10/25/2024, 10:56 AMSELECT SUM({fact/quantity} * (
SELECT LAST_VALUE({fact/price})
ORDER BY {label/sale_date.minute}
WITHIN {label/product_id}
)
)
it gives exactly the same results, but is much easier to understand and might be faster to calculate.Karim Sabaa
10/25/2024, 3:03 PM