2013-09-25 3 views
1

У меня есть таблица Oracle с несколькими столбцами, заполненная переменной, существует большое количество возможных переменных, приведенный ниже пример не является исчерпывающим.Сортировка переменных в записи

ID Col1 Col2 Col3 
-------------------- 
1 A  B 
2 B  A  D 
3 B  C 
4 C  B  
5 B  B 
6 E  D 
7 B  A  C 

Мне нужно создать запрос, который прибегает переменные в каждой строке:

ID Col1 Col2 Col3 
-------------------- 
1 A  B 
2 A  B  D 
3 B  C 
4 B  C  
5 B  B 
6 D  E 
7 A  B  C 

Ищу элегантное решение, как в реальном мире проблема имеет 20 столбцов с до 40 различных переменных (до четырех символов в длину) и несколько миллионов записей.

+1

Что вы пробовали? Какие у вас ошибки? Покажите нам какой-то код. Также пометьте это в sql – hrv

+0

Как мы узнаем, какие столбцы перетасовать? Должен ли быть запрос или может быть хранимой процедурой? –

+0

Что находится в полях, у которых нет «переменной»: 'space' или' NULL'? –

ответ

1

Ниже приведен вариант для Oracle 10g и более поздних версий. Поскольку в исходном наборе данных имеется большое количество строк, я попытаюсь избежать решений, которые включают группировку и аналитические функции поверх полного набора результатов.

Базовая таблица для этого примера:

create table tab1 (
    ID number, 
    col1 varchar2(4), 
    col2 varchar2(4), 
    col3 varchar2(4), 
    col4 varchar2(4) 
) 

Во-первых, собрать все столбцы для каждого ID в отсортированном коллекции:

select 
    tab1.ID, 
    cast(multiset(
    select 
     decode(level, 
     1, tab1.col1, 
     2, tab1.col2, 
     3, tab1.col3, 
     4, tab1.col4, 
     null 
    )  
    from dual 
    connect by level <= 4 
    order by 
     decode(level, 
     1, tab1.col1, 
     2, tab1.col2, 
     3, tab1.col3, 
     4, tab1.col4, 
     null 
    ) 
     nulls last   
) as sys.ODCIVarchar2List) sorted_values 
from tab1; 

Имея такой набор данных, что можно расшифровать значения обратно столбцов при сохранении установленный порядок:

select 
    ID, 
    (
    select column_value 
    from table(data_list.sorted_values) 
    where rownum = 1 
) as col1, 
    (
    select max(decode(rownum, 2, column_value, null)) 
    from table(data_list.sorted_values) 
) as col2, 
    (
    select max(decode(rownum, 3, column_value, null)) 
    from table(data_list.sorted_values) 
) as col3, 
    (
    select max(decode(rownum, 4, column_value, null)) 
    from table(data_list.sorted_values) 
) as col4 
from (
    select 
    rownum, -- this needed as workaround for Oracle bug 
    tab1.ID, 
    cast(multiset(
     select 
     decode(level, 
      1, tab1.col1, 
      2, tab1.col2, 
      3, tab1.col3, 
      4, tab1.col4, 
      null 
     )  
     from dual 
     connect by level <= 4 
     order by 
     decode(level, 
      1, tab1.col1, 
      2, tab1.col2, 
      3, tab1.col3, 
      4, tab1.col4, 
      null 
     ) 
     nulls last   
    ) as sys.ODCIVarchar2List) sorted_values 
    from tab1 
) 
    data_list 

SQLFiddle test

Обратите внимание, что rownum должен присутствовать во внутреннем select пункте как обходной путь для this Oracle error.

+0

Ничего себе, что это хорошее решение. версия SQLFiddle работает. Я получаю код ошибки: 907 ORA-00907: отсутствие правильной круглой скобки, когда я запускаю ее в производстве на Oracle 11.2.0.2.0, любые идеи, что это может быть - код все выглядит нормально ...? – user2798561

+0

@ user2798561 Вы пытались запустить точный код из примера (например, путем копирования и вставки) или уже адаптировали его для своего решения? Возможно ли, что вы действительно пропустили правую скобку в каком-то месте? SQL Fiddle работает точно 11.2.0.2.0 ([доказательная ссылка] (http://sqlfiddle.com/#!4/d41d8/1187)). – ThinkJet

Смежные вопросы