2010-06-25 6 views
7

У меня есть данные таблицы со столбцами:MySQL преобразования нескольких строк в столбцы в одной строке

  • user_id INT
  • код INT
  • значение INT

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

  • user_id int
  • значения а Int
  • Int
  • VALUE млрд

В таблице данных, значение а соответствовало бы сказать, код 5, и будет соответствовать VALUE млрд сказать, код 6, так что я ищу что-то вроде:

Вставить в сводку (user_id, valueA, valueB) VALUES (SELECT ??? от деталей);

Проблема, конечно, в том, что я просматриваю несколько строк из таблицы «details», чтобы заполнить одну строку в таблице «summary».

Например, если я имел следующие строки в деталях:

1 5 100 
1 6 200 
2 5 1000 
2 6 2000 

Я хочу, чтобы в конечном итоге следующее в сводной таблице:

1 100 200 
2 1000 2000 

Любые идеи?

+0

5 вопросов, не принимаются ответ, 0 ответов на вопросы других людей. Вы знаете, что это сайт, основанный на сообществах, а не форум поддержки somecompany, не так ли? – Anax

ответ

8

MySQL не имеет PIVOT/UNPIVOT синтаксис, который оставляет вам использовать комбинацию GROUP BY и CASE-выражения:

INSERT INTO SUMMARY 
    (user_id,valueA,valueB) 
    SELECT d.user_id, 
     MAX(CASE WHEN d.code = 5 THEN d.value ELSE NULL END), 
     MAX(CASE WHEN d.code = 6 THEN d.value ELSE NULL END), 
    FROM DETAILS d 
GROUP BY d.user_id 
+0

Это ответ, который я нашел наиболее полезным. У меня был огромный стол, с которым можно было справиться, и это выполнялось адекватно. – Jack

+0

Отлично, это то, что я искал, для одного из моих SQL. Благодаря! – hese

+0

Fantasic, изменил эту часть: MAX (CASE WHEN d.code = 5 THEN d.value ELSE NULL END), чтобы вернуть значение bool, чтобы определить, соответствует ли категория пользователя определенной категории поиска, или если две категории просто разделяют общую родительская категория. – nealio82

0

Если у вас есть управляемый набор кодов (скажем, только 5 и 6), вы могли бы сделать что-то вроде этого:

SELECT details.user_id, code5.value, code6.value 
FROM details JOIN 
    (SELECT user_id, value FROM details WHERE code = 5) AS code5 USING(user_id) 
    JOIN 
    (SELECT user_id, value FROM details WHERE code = 6) AS code6 USING(user_id); 

Вы, возможно, потребуется изменить свои JOIN с в зависимости от того, если ваши коды не требуется, От 1 до 1 (т.е. LEFT JOIN с).

Если у вас есть большой набор кодов, я бы посмотрел на курсор, который запускает аналогичный запрос выше по набору результатов ваших кодов или использует другую технологию (то есть PHP-скрипт).

2
insert into summary (user_id,valueA,valueB) 
SELECT a.user_id, a.value, b.value 
from details a 
join details b on a.user_id = b.user_id 
WHERE a.code = 5 and b.code = 6; 

Остерегайтесь: в итоге вы получите несколько итоговых столбцов, если код user_id + не уникален. не

EDIT:

insert into summary (user_id,valueA,valueB) 
select u.user_id, ifnull(a.value,0), ifnull(b.value,0) 
from (select distinct user_id from details /* where code in (5,6) */) u 
left join details a on a.user_id = u.user_id and a.code = 5 
left join details b on b.user_id = u.user_id and b.code = 6 
+0

Спасибо! Но я действительно нуждался в 3 значениях, и я изменил приведенное выше «очевидным» способом (добавив другое соединение), и это сработало; но теперь проблема заключается в том, что если какой-либо пользователь пропускает какую-либо из строк (например, имеет A и B, но отсутствует C), то у меня нет строки для этого пользователя.Вместо этого я хотел бы видеть строку с 0 для любых отсутствующих значений из таблицы подробностей. Есть идеи по этому поводу? – Jack

+0

, то вместо этого используйте левое соединение, см. «Edit» –