ENH break histogram function into more convenient chunks

This commit is contained in:
Nathan Dwarshuis 2021-05-30 01:31:00 -04:00
parent 59e5edc066
commit c138528915
1 changed files with 38 additions and 12 deletions

View File

@ -4,36 +4,62 @@ as $$
select ts::time at time zone 'US/Eastern';
$$ language SQL;
CREATE OR REPLACE FUNCTION histogram(tname text, cname text, width int)
RETURNS TABLE(bin_number int, bin_interval text, count bigint)
create or replace function get_bin_num(x numeric, width int)
returns int
as $$
-- select (floor(x/width)*width)::int;
select floor(x/width)::int;
$$ language SQL;
CREATE OR REPLACE FUNCTION bin_ranges(tname text, cname text, width int)
RETURNS TABLE(bin_number int, bin_interval text)
AS $func$
BEGIN
RETURN QUERY EXECUTE format('
with recursive
no_bins_t as (
select min(floor(a.%1$s/%2$s)*%2$s)::int as bin_number from %3$s a
select min(get_bin_num(%1$s,%2$s)) as bin_number from %3$s a
union all
select bin_number + 1 as bin_number from no_bins_t
where
bin_number < (select max(floor(a.%1$s/%2$s)) + 1 from %3$s a)
bin_number < (select max(get_bin_num(%1$s,%2$s)) + 1 from %3$s a)
)
select
bin_number,
concat(bin_number*%2$s, ''-'', bin_number*%2$s + %2$s - 1) as bin_interval,
case when count is null then 0 else count end as count
concat(bin_number*%2$s, ''-'', bin_number*%2$s + %2$s - 1) as bin_interval
from no_bins_t
left join
(select
floor(a.%1$s/%2$s)*%2$s as ab_floor,
order by no_bins_t.bin_number;',
cname,
width,
tname
);
END
$func$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION histogram(tname text, cname text, width int)
RETURNS TABLE(bin_number int, bin_interval text, count bigint)
AS $func$
BEGIN
RETURN QUERY EXECUTE format('
with binned as (
select
get_bin_num(%1$s,%2$s) as ab_floor,
count(*) as count
from %3$s a
group by ab_floor
order by ab_floor) as binned
on no_bins_t.bin_number*%2$s=binned.ab_floor
order by no_bins_t.bin_number;',
order by ab_floor
)
select
bin_number,
bin_interval,
case when b.count is null then 0 else b.count end as count
from bin_ranges(''%3$s'',''%1$s'',%2$s) r
left join binned b on r.bin_number=b.ab_floor
order by r.bin_number;',
cname,
width,
tname