I have a table like this:
id timestamp alive
1 2019-10-10 true
2 2019-10-10 false
... ......... .....
N 2021-01-01 boolean
What I need:
Extract by year and month how many true and false and the relation false/true the table has. Like this:
Period True False false/true
JAN-2019 1000 10 0.01
What I tried:
I did some cte using date_trunc but I got so many fails that I gave up.
CodePudding user response:
You can use the following:
with agg as (
select cnv."Period"
,sum(case when alive then 1 end) as "True"
,sum(case when not alive then 1 else 0 end) as "False"
from (values -- vvvvvvvvvvvvvvvvvvvv
(1,'2019-10-10'::date, true ) -- replace this values()
,(2,'2019-10-10' , false) -- table with your
,(3,'2021-01-01' , false) -- actual table
) dat(id,"timestamp",alive) -- ^^^^^^^^^^^^^^^^^^^^
cross join lateral (select to_char(dat."timestamp",'YYYY-MM')) cnv("Period")
group by cnv."Period"
)
select *
,("False" * 1.0 / "True")::numeric(10,2) as "false/true"
from agg
order by "Period"
;
- The lateral join just converts the date to
yyyy-mmformat once, so the result can be referenced multiple times - The CTE counts the number of true & false once, so the results can be referenced in the ratio calculation. Note that by leaving out the
elseon thecasestatements, thesum()will returnnullfor periods in which there are no occurrences oftrue. The ratio will then shownullrather than produce a divide by zero error - The ratio calculation multiplies the integer value by a
numericvalue to avoid integer division rounding. It then casts the result to a numeric type with 2 decimal places.
CodePudding user response:
You can use a FILTER clause for each condition (alive and not alive) and then aggregate it by the formatted timestamp using to_char, e.g.
SELECT
to_char(timestamp,'MON-YYYY'),
count(*) FILTER (WHERE alive) AS alive,
count(*) FILTER (WHERE NOT alive) AS not_alive,
count(*) FILTER (WHERE alive)::numeric /
nullif(count(*) FILTER (WHERE NOT alive),0)::numeric AS "true/false"
FROM t
GROUP BY to_char(timestamp,'MON-YYYY');
Demo: db<>fiddle
