I have a table:
campaign_id | media | installs | content_view | date | unique_purchase |
---|---|---|---|---|---|
7564 | 613 | 45 | 2021-09-01 | 1 | |
7564 | 21 | 33 | 2021-09-02 | 2 | |
3451 | 83 | 12 | 2021-09-01 | 0 |
I want to create view:
- write
installs
column values asmetric_key=installs
,metric_name=installs
,metric_value=...
- write
content_view
andunique_purchase
asmetric_key=event
,metric_name=column_name
,metric_value=...
id | media_source | metric_key | metric_name | metric_value | date |
---|---|---|---|---|---|
7564 | installs | installs | 613 | 2021-09-01 | |
7564 | installs | installs | 21 | 2021-09-02 | |
3451 | installs | installs | 83 | 2021-09-01 | |
7564 | event | unique_purchase | 1 | 2021-09-01 | |
7564 | event | unique_purchase | 2 | 2021-09-02 | |
3451 | event | unique_purchase | 0 | 2021-09-01 | |
7564 | event | content_view | 45 | 2021-09-01 | |
7564 | event | content_view | 33 | 2021-09-02 | |
3451 | event | content_view | 12 | 2021-09-01 |
Also it should be groupped by campaign_id
, media
, date
.
How to achieve it with Postgres? I dont understand crosstab
clearly. Thanks!
CodePudding user response:
Use a lateral join
:
select t.id, t.media_source, v.*, t.date
from t cross join lateral
(values ('installs', t.installs, 'installs'),
('event', t.unique_purchase, 'unique_purchase'),
('event', t.content_view, 'content_view')
) v(metric_key, metric_name, metric_value);
CodePudding user response:
You can select specific subset of data and stack them on top of each other. One can assign column names directly in the select
queries instead of using a CTE
. It's just a personal preference.
create view my_metric_view as
with cte (id, media_source, metric_key, metric_name, metric_value, date) as
(select campaign_id,
media,
'installs',
'installs',
installs,
date
from t
where metric_name='installs'
union all
select campaign_id,
media,
'event',
'unique_purchase',
unique_purchase,
date
from t
where metric_name='unique_purchase'
union all
select campaign_id,
media,
'event',
'content_view',
content_view,
date
from t
where metric_name='content_view')
select *
from cte;