W Oracle 11.1 i nowszych możesz użyć UNPIVOT
operator. Jeśli masz dużą ilość danych, zapewni to znaczną poprawę czasu wykonania, ponieważ wymaga odczytania tabeli tylko raz, zamiast trzykrotnego przy użyciu dowolnego rodzaju UNION ALL
podejście.
Zmieniłem nazwę kolumny (w wyniku) z date
do dt
ponieważ DATE jest słowem zastrzeżonym w Oracle. type
nie jest dużo lepszy (jest to słowo kluczowe, ale nie jest zastrzeżone); najlepiej też tego unikać. Traktowałem również twoje daty jako ciągi podczas tworzenia danych testowych, ale działa to tak samo z datami.
with
klauzula nie jest częścią rozwiązania (nie kopiuj i nie wklejaj jej na ślepo wraz z zapytaniem); Dodałem go tylko w celach testowych.
with
test_data ( ID, VT_Type1, Vt_type2, VT_Type3, Status_1, Status_2, Status_3,
Date_1, Date_2, Date_3 ) as (
select 1, -1, -1, 0, 'X', 'Y', 'Z', '04/12', '05/12', '06/12' from dual union all
select 2, -1, -1, -1, 'A', 'B', 'C', '06/12', '07/12', '07/10' from dual
)
select id, type, status, dt
from test_data
unpivot ( (vt_type, status, dt) for type in ( (vt_type1, status_1, date_1) as 1,
(vt_type2, status_2, date_2) as 2,
(vt_type3, status_3, date_3) as 3
)
)
where vt_type != 0
;
ID TYPE STATUS DT
-- ---- ------ -----
1 1 X 04/12
1 2 Y 05/12
2 1 A 06/12
2 2 B 07/12
2 3 C 07/10