2012-03-23 4 views
1

У меня есть таблица, подобный следующему:Pivot Несколько Ряды

id key str_val date_val  num_val 
1  A  a 
1  B  b 
1  C     2012-01-01 
1  D        1 
2  A  c 
2  E  d 
2  C     2012-01-02 
2  D        2 

мне нужно, чтобы это выглядело как:

id A  B  C    D  E 
1  a  b  2012-01-01 1 
2  c    2012-01-02 2  d 

В принципе, каждый ключ должен стать его собственный столбец

Я попытался и не смог использовать команду PIVOT с пользой, и в настоящее время я пытаюсь выполнить это с помощью case-case. то есть

select 
    id, 
    case key 
     when 'A' 
     then str_val 
    end as A, 
    case key 
     when 'C' 
     then date_val 
    end as C 
    --etc. 
from test_table 

Однако я не могу понять, как объединить строки таблицы после этого. Я застрял в:

id A  B  C    D  E 
1  a 
1   b 
1     2012-01-01 
1         1 

Любые мысли или ввод, которые могут мне помочь? Заранее спасибо.

+1

Знаете ли вы, будет ли все в столбце результата «A» (строки с ключом «A» в исходной таблице) одинаковым типом данных? Например, в вашем примере все Cs являются Date или DateTime, гарантируется ли это? И есть только одна строка на каждую пару id/Key? Я думаю, что в основном вы хотите UNPIVOT (используя ключевое слово или UNION) str_val, dateval, numval для каждой строки, а затем сворачивать результаты, используя старинный синтаксис Max CASE (...) как A ". –

+0

@LevinMagruder Ваши предположения верны. Я должен буду попробовать. –

+0

На самом деле ответ Криса Келли и Гавина Кэттеля, вероятно, лучше. Хотя это не причина, чтобы не попробовать их всех. –

ответ

3

Вы 90% пути там :

with cte as (
    select 
     id, 
     case [key] 
      when 'A' 
      then str_val 
     end as A, 
     case [key] 
      when 'B' 
      then str_val 
     end as B, 
     case [key] 
      when 'C' 
      then date_val 
     end as C, 
     case [key] 
      when 'D' 
      then num_val 
     end as D, 
     case [key] 
      when 'E' 
      then str_val 
     end as E 
    from test_table 
) 
select id, max(A) as A, max(B) as B, max(C) as C, max(D) as D, max(E) as E 
from cte 
group by id 
+0

А, спасибо. Это прекрасно работает! –

2

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

SELECT ta.str_val as A, 
     tb.str_val as B, 
     tc.date_val as C, 
     td.num_val as D, 
     te.str_val as E 
FROM (SELECT DISTINCT id FROM test_table) ids 
LEFT JOIN test_table ta ON ids.id = ta.id AND ta.key = 'A' 
LEFT JOIN test_table tb ON ids.id = tb.id AND tb.key = 'B' 
LEFT JOIN test_table tc ON ids.id = tc.id AND tc.key = 'C' 
LEFT JOIN test_table td ON ids.id = td.id AND td.key = 'D' 
LEFT JOIN test_table tc ON ids.id = te.id AND te.key = 'E'; 

В этом запросе вы получите все идентификаторы (если вы можете ответить на колонке «A» всегда там вы можете начать с этого). Затем вам нужно присоединиться к каждой клавише для данного идентификатора.

Если вы не можете полагаться на тип данных ключа, т.е. может быть строка или дата, то вы должны использовать следующее для каждого выбора:

COALESCE(ta.str_val,TO_CHAR(ta.date_val,'DD-MM-YYYY'),TO_CHAR(ta.num_val)) A, 
COALESCE(tb.str_val,TO_CHAR(tb.date_val,'DD-MM-YYYY'),TO_CHAR(tb.num_val)) B, 
... 
etc. 
+0

+1 при обработке нескольких типов данных, хотя OP не нуждался в нем. –

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