Я знаю, что это долго и не пуленепробиваемым, но это своего рода делает работу.
WITH source_t AS
(
SELECT 100 id, 'Albert' name, 'Kevin' name2, 'Jon' name3, 'Alex' name4 FROM DUAL UNION ALL
SELECT 101, 'Albert', 'Jon', 'Kevin', 'Alex' FROM DUAL UNION ALL
SELECT 102, 'Albert', 'Georg', 'Alex', 'Babera' FROM DUAL UNION ALL
SELECT 103, 'Albert', 'Stefany', NULL, NULL FROM DUAL
)
, tab_1 AS
(
SELECT id, name, name2 FROM source_t UNION ALL
SELECT id, name, name3 FROM source_t UNION ALL
SELECT id, name, name4 FROM source_t
)
, tab_2 AS
(
SELECT id
, name
, name2
, ROW_NUMBER() OVER (PARTITION BY id, name ORDER BY name2) AS r_number
FROM tab_1
)
, tab_3 AS
(
SELECT id
, name
, MAX(CASE WHEN r_number = 1 THEN name2 END) AS name2
, MAX(CASE WHEN r_number = 2 THEN name2 END) AS name3
, MAX(CASE WHEN r_number = 3 THEN name2 END) AS name4
FROM tab_2
GROUP BY
id
, name
)
SELECT tab_3.id
, tab_3.name
, tab_3.name2
, tab_3.name3
, tab_3.name4
, tab_4.n_count
FROM tab_3
LEFT JOIN
(
SELECT name
, name2
, name3
, name4
, COUNT(1) AS n_count
FROM tab_3
GROUP BY
name
, name2
, name3
, name4
) tab_4
ON tab_3.name = tab_4.name
and NVL(tab_3.name2, 'NULL') = NVL(tab_4.name2, 'NULL')
and NVL(tab_3.name3, 'NULL') = NVL(tab_4.name3, 'NULL')
and NVL(tab_3.name4, 'NULL') = NVL(tab_4.name4, 'NULL')
;
/*
102 Albert Alex Babera Georg 1
103 Albert Stefany NULL NULL 1
101 Albert Alex Jon Kevin 2
100 Albert Alex Jon Kevin 2
*/
Схема предназначена для того, чтобы сделать это невыносимо тяжелым. Нормализовать данные, и это будет проще (непросто, но проще). –
Вы не поняли, факт, что в вашем примере (от 100 до 101) вы указываете, что существует только одно одно совпадение, означает, что вы хотите, чтобы позиция имени считалась так же, как и значение (все три имени находятся в обоих рядах где-то). Можете ли вы пояснить, что означает значение столбцов в этой схеме, и что именно вы пытаетесь сделать? –
Я пытаюсь создать новый идентификатор, скажем, ID2, который будет иметь одинаковое значение для строк 100 и 101 и отличается для 102 и 103. – user2963882