Reputation: 57
so i have this table in google-bigquery as shown below
initial table
month | gender | sales | quantity |
Jan-2022 | male. | 2000. | 50. |
Jan-2022 | female. | 3000. | 100. |
and this is my desired table
month |metrics. |overall | male |composition (%)|female|composition (%)|
Jan-22|sales. | 5000. | 2000.| 40% |3000 | 60% |
Jan-22|quantity. | 150. | 50.| 33% | 100 | 66% |
so what query to use to get the desired result?
Upvotes: 0
Views: 74
Reputation: 172993
Consider below approach
select * from (
select *,
sum(col) over month_metric overall,
round(100 * (sum(col) over month_metric_gender) / (sum(col) over month_metric), 0) composition
from your_table
unpivot (col FOR metrics IN (sales, quantity))
window
month_metric as (partition by month, metrics),
month_metric_gender as (partition by month, metrics, gender))
pivot (sum(col) gender, any_value(composition) composition for gender in ('male', 'female'))
if applied to sample data in your question - output is
The reason I would recommend above approach over previous (first answer you've got) - is that it is more generic and does not have dependency on explicitly calling out columns like male
, femail
(with except of in pivot statement of course)
Upvotes: 1
Reputation: 1305
You basically want to transform columns into rows and transform rows into columns. For that, you can use the UNPIVOT
and PIVOT
operators.
This gives you the desired output:
WITH your_table AS
(
SELECT 'Jan-2022' AS month, 'male' AS gender, 2000 AS sales, 50 AS quantity
UNION ALL
SELECT 'Jan-2022', 'female', 3000, 100
)
SELECT
month,
metrics,
(male + female) AS overall,
male,
male / (male + female) AS male_composition,
female,
female / (male + female) AS female_composition
FROM
(
SELECT *
FROM
your_table
UNPIVOT(vals FOR metrics IN (sales, quantity))
) PIVOT(SUM(vals) FOR gender IN ('male', 'female'))
Upvotes: 3