add batch remove batch split batch comment selection show hidden batches hide batch highlight batch
db<>fiddle
donate feedback about
By using db<>fiddle, you agree to license everything you submit by Creative Commons CC0.
Help with an interesting Postgres question: Why isn't an Index Only Scan used on a partition accessed via the parent table?.
CREATE TABLE assets (
id serial PRIMARY KEY
, name text
, owner text
);

CREATE TABLE users (
id serial PRIMARY KEY
, username text
, ref1 text
, ref2 text
);

INSERT INTO assets (name, OWNER) VALUES
('#1', 'a')
, ('#2', 'b')
, ('#3', 'c')
, ('#4', 'a')
, ('#5', 'c')
, ('#6', 'd')
, ('#7', 'e')
, ('#8', 'd')
, ('#9', 'a')
, ('#10', 'a')
, ('#11', 'z')
;

INSERT INTO users (username, ref1, ref2) VALUES
('bobo', 'a', 'd')
, ('toto', 'b', 'e')
, ('momo', 'c', 'd')
, ('lolo', 'a', 'f')
, ('popo', 'c', 'f')
;

-- For result comparison
CREATE TABLE
CREATE TABLE
INSERT 0 11
INSERT 0 5
CREATE TABLE
INSERT 0 2
ids usernames refs1 refs2 asset_ids asset_count
{1,3,4,5} {bobo,momo,lolo,popo} {a,c} {d,f} {1,3,4,5,6,8} 6
{2} {toto} {b} {e} {2,7} 2
SELECT 2
SHOW temp_buffers;
temp_buffers
8MB
SHOW
CREATE OR REPLACE FUNCTION f_merged_users()
RETURNS TABLE (
ids int[] -- adapt to your actual data types !!!
, usernames text[]
, refs1 text[]
, refs2 text[]
, asset_ids int[]
, asset_count int
)
LANGUAGE plpgsql AS
$func$
BEGIN
/*
-- Set enough temp buffers, so temp tables don't spill to disk (optional)
-- NOTE: this can't be used after temporary tables have been accessed in the session
-- Using 2x size of users table. Adapt to your needs!
-- Only fires when the new size is bigger, and it has not been set manually, yet
PERFORM set_config('temp_buffers', (pg_table_size('users') * 2 / 8096)::text, true)
FROM pg_settings s
WHERE s.name = 'temp_buffers'
AND pg_table_size('users') * 2 / 8096 > s.setting::bigint
AND s.source = 'default';
*/

-- create two temp tables: one for ref1, one for ref2
-- based on the assumption that ref1 & ref2 don't overlap
CREATE TEMP TABLE r1 ON COMMIT DROP AS
SELECT ARRAY[ref1] AS r, array_agg(id) AS i
FROM (TABLE users ORDER BY id) t
GROUP BY ref1
ORDER BY ref1;

CREATE TEMP TABLE r2 ON COMMIT DROP AS
SELECT ARRAY[ref2] AS r, array_agg(id) AS i
FROM (TABLE users ORDER BY id) t
GROUP BY ref2
CREATE FUNCTION
SELECT * FROM f_merged_users();
ids usernames refs1 refs2 asset_ids asset_count
{1,3,4,5} {bobo,momo,lolo,popo} {a,c} {d,f} {1,3,4,5,6,8,9,10} 8
{2} {toto} {b} {e} {2,7} 2
null null null {z} {11} 1
SELECT 3