cr_bucket_dedicated_code.sql
This page documents a preview version.
v2.23 Preview
Preview includes features under active development and is for development and testing only.
For production, use the latest stable version (v2024.1).
For production, use the latest stable version (v2024.1).
Save this script as cr_bucket_dedicated_code.sql
.
-- This approach implements the required "open-closed" interval
-- bucket semantics directly. See the test
--
-- where scaled_val > lb and scaled_val <= ub
--
-- at the end.
--
-- You might consider this to be the better approach, even though
-- it means saying "No thank you" to the free gift of the built-in
-- "width_bucket()" which -- acutally implements the wrong semantics
-- for the present use case. Fixing it up with a trick might feel to be
-- too offensive.
--
-- This implementation of "bucket()" also passes the rigorous
-- acceptance test.
create or replace function bucket(
val in double precision,
lower_bound in double precision default 0,
upper_bound in double precision default 1,
no_of_values in int default 10)
returns int
language plpgsql
as $body$
begin
assert
(val between lower_bound and upper_bound),
'bucket():'||
' val '||val||
' must be between lower_bound '||lower_bound||
' and upper_bound '||upper_bound;
declare
one constant double precision := 1;
n constant double precision := no_of_values;
scaled_val constant double precision :=
(val - lower_bound)/(upper_bound - lower_bound);
begin
return (
with
series as (
select generate_series::int as s
from generate_series(1::int, no_of_values))
,
buckets as (
select
s as bucket,
-- (val = 0) is defined to be in (bucket = 1)
case s when 1 then
-one
else
((s::double precision) - one)/n
end as lb,
(s::double precision)/n as ub
from series)
select bucket
from buckets
where scaled_val > lb and scaled_val <= ub
);
end;
end;
$body$;