Skip to content

Instantly share code, notes, and snippets.

@diraneyya
Last active August 28, 2025 17:33
Show Gist options
  • Save diraneyya/94558c71699e3c6ddc96d2c31c587486 to your computer and use it in GitHub Desktop.
Save diraneyya/94558c71699e3c6ddc96d2c31c587486 to your computer and use it in GitHub Desktop.
`coalesce_equal(...)` is a PostgreSQL function that is similar to `coalesce`, but requires that all non-null arguments be equal for it to return the identical value, when not equal or all arguments are null, it returns null.
-- Similar to coalesce, but only gives back a non-null value if all the non-null
-- params are equivalent.
create or replace function coalesce_equal(variadic args anycompatiblearray)
returns anycompatible language sql immutable as $$
with all_args(arg) as (select unnest(args)), dist_args(count) as (
select count(distinct arg) filter (where arg is not null) from all_args
)
select arg from all_args, dist_args
where arg is not null and count = 1
limit 1
$$;
-- tests
select coalesce_equal('f', null, 'f', null, 'ff', 'f'); -- gives NULL
select coalesce_equal('f', null, 'f', null, 'f', 'f'); -- gives 'f'
select coalesce_equal(6, null, 7, null, 6, null); -- gives NULL
select coalesce_equal(6, null, 6, null, 6, null); -- gives 6
select coalesce_equal(null, null, null, null, null, null); -- gives NULL
select coalesce_equal('f', null, 6, null, false, 'f'); -- gives ERROR 😱
-- Similar to nullif, but only gives back a the value if all the params are
-- equivalent to this value.
create or replace function valueif(variadic args anycompatiblearray)
returns anycompatible language sql immutable as $$
with args(arg) as (select distinct * from unnest(args))
select any_value(arg) from args having count(*) = 1
$$;
-- tests
select valueif('f', 'f', 'f', 'f', 'f'); -- gives 'f'
select valueif('f', 'f', 'f', 'ff', 'ff', 'f'); -- gives NULL
select valueif('f', null, 'f', null, 'ff', 'f'); -- gives NULL
select valueif(6, null, 7, null, 6, null); -- gives NULL
select valueif(6, 6, 6); -- gives 6
select valueif(6, null, 6, null, 6, null); -- gives NULL
select valueif(null, null, null, null, null, null); -- gives NULL
select valueif('f', null, 6, null, false, 'f'); -- gives ERROR
select valueif(true, false); -- gives NULL
select valueif(0, false); -- gives ERROR
select valueif(false, false); -- gives False
select valueif(null); -- gives NULL
select valueif(true); -- gives True
@diraneyya
Copy link
Author

Coalesce Equal as an Aggregate Function

The utility function, coalesce_equal, can also be used to define a very useful aggregate.

-- "s" stands for state, "v" stands for value, "sf" stands for state (transition) function
create or replace function sf_coalesce_equal(s anyelement, v anyelement)
  returns anyelement language sql immutable strict as $$ 
  select coalesce_equal(s, v) $$;

drop aggregate if exists coalesce_equal_agg(anyelement);
create aggregate coalesce_equal_agg(anyelement) (
  sfunc = sf_coalesce_equal,
  msfunc = sf_coalesce_equal,
  minvfunc = sf_coalesce_equal,
  mstype = anyelement,
  stype = anyelement
  );

@diraneyya
Copy link
Author

Reflection

I am proposing to rename the aggregate version from coalesce_equal_agg to coalesceif.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment