2014-01-20 3 views
0

Это база данных исследований, в которой есть (да, я знаю плохо спроектированную) базу данных, которая включает анкету для участников. Эта анкета запрашивается у участника три раза в исследовании (P1/P2/P3)Как преобразовать несколько строк в одну строку

Структура таблицы для вопросника;

Вопросник 1.

+--+-------+--------+--+--+--+--+--+--- 
|PK|Part_ID|Phase_Id|Q1|q2|q3|q4|q5|... 
+--+-------+--------+--+--+--+--+--+--- 
|1 |A010 |P1  |1 |0 |1 |0 |1 |... 
+--+-------+--------+--+--+--+--+--+--- 
|2 |A010 |P2  |0 |1 |0 |1 |0 |... 
+--+-------+--------+--+--+--+--+--+--- 
|3 |A010 |P3  |1 |0 |1 |0 |1 |... 
+--+-------+--------+--+--+--+--+--+--- 

так далее для каждого участника.

Все участники имеют максимум 3 фаз, возможно, меньше. Из-за столбцов столбцов столбцов всегда один и тот же.

Исследователь хочет получить все данные на одной строке для ввода в аналитическую программу (SPSS). Поэтому структура вывода должна выглядеть так:

+-------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 
|Part_ID|P1_Q1|P1_q2|P1_q3|P1_q4|P1_q5|P2_Q1|P2_q2|P2_q3|P2_q4|P2_q5|P3_Q1|P3_q2|P3_q3|P3_q4|P3_q5| 
+-------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 
|A010 |1 |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 | 
+-------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 

Использование SQL Server 2008 Express.

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

Так что любые указатели были бы замечательными.

С уважением

Роджер (я надеюсь, что формат демо выходит нормально).

+0

Вы имеете в виду один ряд *** для участника *** правильно? –

+0

Мартин - Да, спасибо. 1 строка на участника – Darklantern

+0

Как вы отформатировали это в формате таблицы? – Darklantern

ответ

1

Вы можете UPIVOT таблицу первой и PIVOT снова

SELECT Part_Id, 
     P1_Q1, P1_Q2, P1_Q3, P1_Q4, P1_Q5, 
     P2_Q1, P2_Q2, P2_Q3, P2_Q4, P2_Q5, 
     P3_Q1, P3_Q2, P3_Q3, P3_Q4, P3_Q5 
    FROM 
(
    SELECT Part_ID, Phase_Id + '_' + Question Question, Value 
    FROM 
    ( 
    SELECT Part_ID, Phase_Id, q1, q2, q3, q4, q5 
     FROM Table1 
) s 
    UNPIVOT 
    ( 
    Value FOR Question IN (q1, q2, q3, q4, q5) 
) u 
) s 
PIVOT 
(
    MAX(Value) FOR Question IN 
    (
    P1_Q1, P1_Q2, P1_Q3, P1_Q4, P1_Q5, 
    P2_Q1, P2_Q2, P2_Q3, P2_Q4, P2_Q5, 
    P3_Q1, P3_Q2, P3_Q3, P3_Q4, P3_Q5 
) 
) p 

или с помощью условного агрегацию

SELECT Part_Id, 
     MAX(CASE WHEN Phase_id = 'P1' THEN Q1 END) P1_Q1, 
     MAX(CASE WHEN Phase_id = 'P1' THEN Q2 END) P1_Q2, 
     MAX(CASE WHEN Phase_id = 'P1' THEN Q3 END) P1_Q3, 
     MAX(CASE WHEN Phase_id = 'P1' THEN Q4 END) P1_Q4, 
     MAX(CASE WHEN Phase_id = 'P1' THEN Q5 END) P1_Q5, 
     MAX(CASE WHEN Phase_id = 'P2' THEN Q1 END) P2_Q1, 
     MAX(CASE WHEN Phase_id = 'P2' THEN Q2 END) P2_Q2, 
     MAX(CASE WHEN Phase_id = 'P2' THEN Q3 END) P2_Q3, 
     MAX(CASE WHEN Phase_id = 'P2' THEN Q4 END) P2_Q4, 
     MAX(CASE WHEN Phase_id = 'P2' THEN Q5 END) P2_Q5, 
     MAX(CASE WHEN Phase_id = 'P3' THEN Q1 END) P3_Q1, 
     MAX(CASE WHEN Phase_id = 'P3' THEN Q2 END) P3_Q2, 
     MAX(CASE WHEN Phase_id = 'P3' THEN Q3 END) P3_Q3, 
     MAX(CASE WHEN Phase_id = 'P3' THEN Q4 END) P3_Q4, 
     MAX(CASE WHEN Phase_id = 'P3' THEN Q5 END) P3_Q5 
    FROM Table1 
GROUP BY Part_Id; 

Выход:

 
| PART_ID | P1_Q1 | P1_Q2 | P1_Q3 | P1_Q4 | P1_Q5 | P2_Q1 | P2_Q2 | P2_Q3 | P2_Q4 | P2_Q5 | P3_Q1 | P3_Q2 | P3_Q3 | P3_Q4 | P3_Q5 | 
|---------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------| 
| A010 |  1 |  0 |  1 |  0 |  1 |  0 |  1 |  0 |  1 |  0 |  1 |  0 |  1 |  0 |  1 | 

Вот SQLFiddle демо

+0

Очень ценю ваш всеобъемлющий ответ и пример. Я нахожусь в процессе адаптации этого к нашей живой информации и вернусь к вам. У меня есть 1 вопрос, как работает 'Phase_Id + '_' + Question Question'. Я не совсем понимаю вопрос «вопрос» – Darklantern

+0

Максимальное агрегирование было бы интересным в отношении того, насколько дорогостоящим будет обработка. Я посмотрю, смогу ли я выполнить план. Мне нравится сценарий скрипта SQL ..... – Darklantern

+0

Вы очень желанны. После столбца unsivot 'question' содержит значения' q1, q2, q3 и т. Д. '.Затем во внешних значениях выбора «Фаза_Ид» и «Вопрос» объединяются, чтобы сформировать значения (например, «P1_Q1'), чтобы стать именами столбцов после поворота. – peterm

0

Если число фаз максимум 3, то вы можете использовать LEFT JOIN с, например, что-то вроде:

SELECT p1.Part_ID, p1.q1, p1.q2, p1.q3, p1.etc, 
p2.Part_ID, p2.q1, p2.q2, p2.q3, p2.etc, 
p3.Part_ID, p3.q1, p3.q2, p3.q3, p3.etc, 
FROM Questionaire p1 
LEFT JOIN Questionaire p2 ON p1.Part_ID = p2.Part_ID AND p1.PhaseId='P1' AND p2.PhaseId='P2' 
LEFT JOIN Questionaire p3 ON p2.Part_ID = p3.Part_ID AND p3.PhaseId='P3' 

Я не пробовал, так что синтаксис может быть не совсем правильно (например вам могут потребоваться скобки).

+0

Спасибо за это, я в настоящее время реализовал этот стиль решения, но он очень медленный. Я пытался быть умным относительно кодирования и иметь более эффективную обработку. Но оцените усилия, чтобы ответить. Roger – Darklantern

+0

Нет никакой причины, по которой простые соединения, подобные этому, должны быть медленными. У вас есть индексы на Questionnaire.Part_ID и Questionnaire.PhaseId? –

+0

Наверное, ни один указатель и havent не смог справиться с проблемой ... Он работает на рабочем столе с помощью SQl express, поэтому я не удивился, что для создания потребуется несколько минут. Я поставлю индексы на место, чтобы убедиться, что это ускоряет работу. Спасибо за дополнительный намек здесь. – Darklantern

0
SELECT Part_ID, SUM(P1_Q1) P1_Q1, SUM(P1_Q2) P1_Q2, SUM(P1_Q3) P1_Q3, 
SUM(P1_Q4) P1_Q4, SUM(P1_Q5) P1_Q5, SUM(P2_Q1) P2_Q1, SUM(P2_Q2) P2_Q2, 
SUM(P2_Q3) P2_Q3, SUM(P2_Q4) P2_Q4, SUM(P2_Q5) P2_Q5, SUM(P3_Q1) P3_Q1, 
SUM(P3_Q2) P3_Q2, SUM(P3_Q3) P3_Q3, SUM(P3_Q4) P3_Q4, SUM(P3_Q5) P3_Q5 
FROM 
( 
SELECT Part_ID,P1_Q1,P1_Q2,P1_Q3,P1_Q4,P1_Q5,P2_Q1,P2_Q2,P2_Q3,P2_Q4,P2_Q5, 
P3_Q1,P3_Q2,P3_Q3,P3_Q4,P3_Q5,P4_Q1,P4_Q2,P4_Q3,P4_Q4,P4_Q5,P5_Q1,P5_Q2,P5_Q3, 
P5_Q4,P5_Q5 
FROM 
(SELECT PK, Part_Id, Phase_id, Q1, Q2, Q3, Q4, Q5, Phase_id +'_Q1' AS LocQ1, 
Phase_id + '_Q2' LocQ2, Phase_id + '_Q3' LocQ3, Phase_id + '_Q4' LocQ4, 
Phase_id+'_Q5' LocQ5 
FROM #t) AS pvt 
PIVOT(SUM(Q1) FOR LocQ1 IN (P1_Q1, P2_Q1, P3_Q1, P4_Q1, P5_Q1)) AS pvt1 
PIVOT(SUM(q2) FOR LocQ2 IN (P1_Q2, P2_Q2, P3_Q2, P4_Q2, P5_Q2)) AS pvt2 
PIVOT(SUM(q3) FOR LocQ3 IN (P1_Q3, P2_Q3, P3_Q3, P4_Q3, P5_Q3)) AS pvt3 
PIVOT(SUM(q4) FOR LocQ4 IN (P1_Q4, P2_Q4, P3_Q4, P4_Q4, P5_Q4)) AS pvt4 
PIVOT(SUM(q5) FOR LocQ5 IN (P1_Q5, P2_Q5, P3_Q5, P4_Q5, P5_Q5)) AS pvt5 
) x GROUP BY Part_ID 
+0

Это похоже на решение Peterm, но я бы рассмотрел стоимость при выполнении этого запроса с количественным коэффициентом агрегации. Спасибо за усилия в ответе. – Darklantern

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