I have this table.
Column name | Data Type |
---|---|
id | uuid |
origin | uuid |
type | varchar(31) |
date | timestamp |
Example records:
id | origin | type | date |
---|---|---|---|
1 | 1111 | A | 2021-11-09 10:01:31.001 |
2 | 1111 | A | 2021-11-08 03:02:22.020 |
3 | 1111 | B | 2021-10-01 11:03:13.003 |
4 | 2222 | A | 2021-11-07 13:04:54.040 |
5 | 3333 | B | 2021-11-09 20:05:45.005 |
6 | 3333 | B | 2021-11-08 21:06:36.060 |
7 | 3333 | B | 2021-11-08 00:07:27.700 |
I'd like to make a SQL query that generates a report showing the percentage of origin
s that has each type
, or both, in the last 7 days (date
column). There are several records for the same origin
.
Desired example result:
PercentageOfOriginThatHasTypeAInLast7Days | PercentageOfOriginThatHasTypeBInLast7Days | PercentageOfOriginThatHasBothTypeInLast7Days |
---|---|---|
66.66 | 33.33 | 0 |
How could I do that?
I'm using a PostgreSQL 11.x
CodePudding user response:
here is one way:
select count(*) filter (where xt = 'A' and xt = mt) * 100.0 / count(*) typeA
, count(*) filter (where xt = 'B' and xt = mt) * 100.0 / count(*) typeB
, count(*) filter (where xt <> mt) * 100.0 / count(*) BothTypes
from (
select origin, max(type) xt , min(type) mt
from data
where date > now() - interval '7 days'
group by origin
) t
db<>fiddle here
CodePudding user response:
You can use a cte
:
with cte as (
select r.origin, r.type, count(*) c from records r where r.date >= now() - interval '7 day' group by r.origin, r.type
),
cte1 as (
select c.origin, count(distinct c.type) c1 from cte c group by c.origin
)
select sum(case when c.type = 'A' then 1 end)/cast((select count(*) from cte) as float),
sum(case when c.type = 'B' then 1 end)/cast((select count(*) from cte) as float),
(select count(*) from cte1 c1 where c1.c1 = (select count(distinct c3.type) from records c3))/((select count(*) from cte) as float)
from cte c