У меня есть таблица Redshift с двумя столбцами, которая показывает, какие идентификаторы связаны, то есть принадлежат одному человеку. Я хотел бы сделать сопоставление (дополнительный столбец) с уникальным идентификатором человека с помощью SQL.
Проблема похожа на эту: SQL: создание уникального идентификатора для элемента с несколькими идентификаторами
Однако в моем случае идентификаторы в обоих столбцах имеют различный вид, и поэтому предлагаемое объединяющее решение (t1.epid = t2.pid и т. Д.) Не будет работать.
В приведенном ниже примере 4 отдельных лица используют 9 идентификаторов типа 1 и 10 идентификаторов типа 2.
ID_type1 | ID_type2
---------+--------
1 | A
1 | B
2 | C
3 | C
4 | D
4 | E
5 | E
6 | F
7 | G
7 | H
7 | I
8 | I
8 | J
9 | J
9 | B
Я ищу дополнительный столбец с привязкой к уникальному идентификатору человека. Трудность заключается в правильной идентификации идентификаторов, связанных с такими людьми, как x & z, которые имеют несколько идентификаторов обоих типов. Результат может выглядеть примерно так:
ID_type1 | ID_type2 | ID_real
---------+---------------------
1 | A | z
1 | B | z
2 | C | y
3 | C | y
4 | D | x
4 | E | x
5 | E | x
6 | F | w
7 | G | z
7 | H | z
7 | I | z
8 | I | z
8 | J | z
9 | J | z
9 | B | z
Я написал ниже запрос, который идет до 4 циклов и выполняет работу для небольшого набора данных, однако борется с большими наборами, так как число строк после объединения очень быстро увеличивается в каждом цикле. Я застрял в поиске способов сделать это более эффективным / действенным.
WITH
T1 AS(
SELECT DISTINCT
l1.ID_type1 AS ID_type1,
r1.ID_type1 AS ID_type1_overlap
FROM crossmatch_example l1
LEFT JOIN crossmatch_example r1 USING(ID_type2)
ORDER BY 1,2
),
T2 AS(
SELECT DISTINCT
l1.ID_type1,
r1.ID_type1_overlap
FROM T1 l1
LEFT JOIN T1 r1 on l1.ID_type1_overlap = r1.ID_type1
ORDER BY 1,2
),
T3 AS(
SELECT DISTINCT
l1.ID_type1,
r1.ID_type1_overlap
FROM T2 l1
LEFT JOIN T2 r1 on l1.ID_type1_overlap = r1.ID_type1
ORDER BY 1,2
),
T4 AS(
SELECT DISTINCT
l1.ID_type1,
r1.ID_type1_overlap
FROM T3 l1
LEFT JOIN T3 r1 on l1.ID_type1_overlap = r1.ID_type1
ORDER BY 1,2
),
mapping AS(
SELECT ID_type1,
min(ID_type1_overlap) AS mapped
FROM T4
GROUP BY 1
ORDER BY 1
),
output AS(
SELECT DISTINCT
l1.ID_type1::INT AS ID_type1,
l1.ID_type2,
FUNC_SHA1(r1.mapped) AS ID_real
FROM crossmatch_example l1
LEFT JOIN mapping r1 on l1.ID_type1 = r1.ID_type1
ORDER BY 1,2)
SELECT * FROM output