I am trying to make the below query fragments to contain less repeating data and to look more elegant. Could you please advise?
SELECT
(select gender from jsonb_to_recordset(audience) as x(gender text[]) where x.gender is not null) as gender,
(select age from jsonb_to_recordset(audience) as x(age text[]) where x.age is not null) as age,
(select ethnicity from jsonb_to_recordset(audience) as x(ethnicity text[]) where x.ethnicity is not null) as ethnicity,
(select continent from jsonb_to_recordset(params) as x(continent text[]) where x.continent is not null) as continent,
(select country from jsonb_to_recordset(params) as x(country text[]) where x.country is not null) as country,
(select city from jsonb_to_recordset(params) as x(city text[]) where x.city is not null) as city
FROM user_data
Is it possible to use the array or CTE returning ['gender', 'age', 'ethnicity', 'continent', 'country', 'city'] and to simulate some loop to avoid repeating the above 6 selects?
SELECT jsonb_build_array(
jsonb_build_array(ARRAY(SELECT UNNEST(dpu1.gender) INTERSECT SELECT UNNEST(dpu2.gender)), COALESCE(dpu1.gender, ARRAY[]::text[]), COALESCE(dpu2.gender, ARRAY[]::text[])),
jsonb_build_array(ARRAY(SELECT UNNEST(dpu1.age) INTERSECT SELECT UNNEST(dpu2.age)), COALESCE(dpu1.age, ARRAY[]::text[]), COALESCE(dpu2.age, ARRAY[]::text[])),
jsonb_build_array(ARRAY(SELECT UNNEST(dpu1.ethnicity) INTERSECT SELECT UNNEST(dpu2.ethnicity)), COALESCE(dpu1.ethnicity, ARRAY[]::text[]), COALESCE(dpu2.ethnicity, ARRAY[]::text[])),
jsonb_build_array(ARRAY(SELECT UNNEST(dpu1.continent) INTERSECT SELECT UNNEST(dpu2.continent)), COALESCE(dpu1.continent, ARRAY[]::text[]), COALESCE(dpu2.continent, ARRAY[]::text[])),
jsonb_build_array(ARRAY(SELECT UNNEST(dpu1.country) INTERSECT SELECT UNNEST(dpu2.country)), COALESCE(dpu1.country, ARRAY[]::text[]), COALESCE(dpu2.country, ARRAY[]::text[])),
jsonb_build_array(ARRAY(SELECT UNNEST(dpu1.city) INTERSECT SELECT UNNEST(dpu2.city)), COALESCE(dpu1.city, ARRAY[]::text[]), COALESCE(dpu2.city, ARRAY[]::text[]))
) as values
FROM data_per_user dpu1 CROSS JOIN data_per_user dpu2
WHERE dpu1.user_uuid <> dpu2.user_uuid
Here is the same story - i find intersecting array elements and have to repeat the same conversion 6 times. Is there more elegant approach?
SELECT
jsonb_build_array(
ARRAY[jsonb_array_length(values->0->0), jsonb_array_length(values->0->1), jsonb_array_length(values->0->2)],
ARRAY[jsonb_array_length(values->1->0), jsonb_array_length(values->1->1), jsonb_array_length(values->1->2)],
ARRAY[jsonb_array_length(values->2->0), jsonb_array_length(values->2->1), jsonb_array_length(values->2->2)],
ARRAY[jsonb_array_length(values->3->0), jsonb_array_length(values->3->1), jsonb_array_length(values->3->2)],
ARRAY[jsonb_array_length(values->4->0), jsonb_array_length(values->4->1), jsonb_array_length(values->4->2)],
ARRAY[jsonb_array_length(values->5->0), jsonb_array_length(values->5->1), jsonb_array_length(values->5->2)]
) as scores
FROM matched_users
And here i'm trying to count number of array elements in 2D array - same story. It looks like too many redundant repeating data. Please advise any ways of optimizing those queries.
I'm not asking for the exact solutions, just the ideas would be appreciated.
user_data? It's not quite clear what output you are expecting.{"age": […], "ethnicity": […], "gender": […]}? Would be much easier to deal with, and prevent duplicates (like[{"gender": ["Male"]}, {"gender": ["Female"]}]).