Вы можете использовать следующую инструкцию select для агрегирования некоторых строк.
select ID, min(Field1) Field1, min(Field2) Field2, min(Field3) Field3
from your_table
group by ID
-- Ignore rows where this would lose data
having nvl(count(Field1),0) < 2
and nvl(count(Field2),0) < 2
and nvl(count(Field3),0) < 2
Когда я запускаю это на ваших тестовых данных, я получаю следующий результат.
ID FIELD1 FIELD2 FIELD3
----- ------ ------ ------
2 F D E
Вы можете выполнить цикл в PL / SQL, удалить все строки с идентификатором и вставить одну строку с этими данными.
Возможно, вы могли бы использовать функцию first_value для второго прохода.
Мой инстинкт подсказывает, что эта таблица не может быть должным образом нормализована. Может быть, у вас должна быть отдельная таблица. Это выглядело бы как результат этого запроса:
select id, 'Field1' field_id, Field1 field_value
from your_table
where field1 is not null
union
select id, 'Field2' field_id, Field2 field_value
from your_table
where field2 is not null
union
select id, 'Field3' field_id, Field3 field_value
from your_table
where field3 is not null
order by 1, 2, 3
/
ID FIELD_ F
---- ------ -
1 Field1 A
1 Field1 G
1 Field1 H
1 Field2 B
1 Field3 C
2 Field1 F
2 Field2 D
2 Field3 E
Если вы не можете перенормировать свою таблицу, вы можете попытаться выполнить цикл по одному и тому же запросу (нормализации) в PL / SQL. Вы должны иметь стек для каждого поля и выдвигать значения для каждой строки. При изменении идентификатора вы будете создавать строки, выталкивая поля 1, 2 и 3 из каждого стека, заполняя нулями и повторяя до тех пор, пока все три стека не исчерпаются.
Надеюсь, вы найдете это полезным.