This is a follow-up to:
Based on these sample tables:
data_providers:
id | field_map
--------------
1 | {"segments": "SEGMENT IDS", "full_name": "FULL NAME"}
leads:
id | data_provider_id | email | data
------------------------------------
1 | 201 | hi@hi | {"SEGMENT IDS": "id1,id1,id1,id2,id3", "FULL NAME": "John Doe"}
2 | 201 | xx@xx | {"FULL NAME": "Billy Bob"}
desired output:
data_provider_id | email | full_name | segment
----------------------------------------------
201 | hi@hi | John Doe | id1
201 | hi@hi | John Doe | id2
201 | hi@hi | John Doe | id3
201 | xx@xx | Billy Bob | NULL
I have the following query:
SELECT
leads.data_provider_id,
leads.email,
leads.data->>(p.field_map->>'full_name') AS full_name,
segment
FROM leads
LEFT OUTER JOIN data_providers p ON p.id = leads.data_provider_id
LEFT JOIN LATERAL unnest(string_to_array(leads.data->>(p.field_map->>'segments'), ',')) AS segment ON true
This query is doing 2 particular things:
its joining on
data_providers
table to get thefield_map
column which contains a JSONB mapping if CSV column headers. So something like{"segments": "SEGMENT ID", "full_name": "FULL NAME"}
Within the
data
JSONB column ofleads
, there is a key (which I discover through the field map above) that contains a comma separated string of segment_ids (it comes in a CSV and they chose to put 2 values within 1 row). I want to split it so each segment_id gets its own row (and obviously all other columns remain the same on both rows).
I have 2 goals:
If there is an empty string or the key doesn't exist within the map, I want to return the row but just with NULL for the segment_id. I already got this working by changing
CROSS JOIN
toLEFT JOIN
.I'm trying to remove duplicates in segment ids, so if someone enters 'id1,id1' it should only produce 1 row. I do this because there is a unique index on that column for the materialized view.
I'm currently stuck on #2.