SQL Pivot для бедных.Список вопросов в виде столбцов и ответов на пользователя в одной строке - PullRequest
0 голосов
/ 13 октября 2010

Текущий запрос :

SELECT order_id AS OrderNumber, ordName, ordLastName, question, answer 
FROM cart_survey 
JOIN orders 
    ON cart_survey.order_id=orders.ordID 
JOIN survey_answers 
    ON survey_answers.id=cart_survey.answer_id 
JOIN survey_questions 
    ON survey_questions.id=cart_survey.question_id

Результаты

OrderNumber ordName ordLastName question                        answer
8591        Larry   Marshburn   Type of Surgery:                Colostomy  
8591        Larry   Marshburn   Month of Surgery:               2
8591        Larry   Marshburn   Year of surgery:                2010
8591        Larry   Marshburn   Current Ostomy System Brand:    ConvaTec  
8591        Larry   Marshburn   Degree of Satisfaction:         Somewhat Satisfied  
8593        Melvin  Belcher     Type of Surgery:                Urostomy
8593        Melvin  Belcher     Month of Surgery:               9
8593        Melvin  Belcher     Year of surgery:                2010
8593        Melvin  Belcher     Current Ostomy System Brand:    ConvaTec  
8593        Melvin  Belcher     Degree of Satisfaction:         Very Satisfied  

Как правильно запросить таблицы, чтобы получить результаты, которые будут выглядеть следующим образом? Имя и фамилия в одной строке, а также вопросы для столбцов и ответы для каждого столбца.

Желаемые результаты

OrderNumber ordName ordLastName "Type of Surgery" "Month of Surgery" "Year of Surgery" etc.
8591        Larry   Marshbourn   Colostomy         2                  2010
8593        Melvin  Belcher      Urostomy          9                  2010

Ответы [ 5 ]

6 голосов
/ 15 октября 2010

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

SELECT
     ID,
     SUM(case when question_id = 1 then 1 else 0 end) as sum1,
     SUM(case when question_id = 2 then 1 else 0 end) as sum2,
     SUM(case when question_id = 3 then 1 else 0 end) as sum3
GROUP BY ID

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

1 голос
/ 22 августа 2012

Это известно как PIVOT. Существует два способа выполнить эту операцию со статической или динамической версией.

Статическая версия - это когда вы жестко кодируете значения, чтобы стать столбцами:

SELECT *
FROM
(
  SELECT order_id AS OrderNumber, ordName, ordLastName, question, answer 
  FROM cart_survey 
  JOIN orders 
      ON cart_survey.order_id=orders.ordID 
  JOIN survey_answers 
      ON survey_answers.id=cart_survey.answer_id 
  JOIN survey_questions 
      ON survey_questions.id=cart_survey.question_id
) x
pivot
(
  min(answer)
  for question in ([Type of Surgery:], [Month of Surgery:], 
                [Year of surgery:], [Current Ostomy System Brand:], 
                [Degree of Satisfaction:])
) p

Dynamic Pivot, получает список столбцов во время выполнения:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ', ' + QUOTENAME(question)
                    from survey_questions
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
      = 'SELECT OrderNumber, ordname, orderLastName,' + @cols + ' from 
         (
            SELECT order_id AS OrderNumber, ordName, ordLastName, question, answer 
            FROM cart_survey 
            JOIN orders 
                ON cart_survey.order_id=orders.ordID 
            JOIN survey_answers 
                ON survey_answers.id=cart_survey.answer_id 
            JOIN survey_questions 
                ON survey_questions.id=cart_survey.question_id
         ) x
         pivot 
         (
            min(answer)
            for question in (' + @cols + ')
         ) p '

execute(@query)
1 голос
/ 13 октября 2010

Это называется сводной точкой, где информация в строках используется для определения списка столбцов. Этот тип запроса требует динамически вычисляемого SQL, если он выполняется полностью в запросе, и обычно вместо этого лучше подходит для форматирования на стороне клиента (многие инструменты называют его сводным или перекрестным запросом, SSRS называет его матричным запросом). *

0 голосов
/ 15 октября 2010

Это версия MySQL

SELECT o . * , 
q1.answer AS  'Type of Surgery:',
q2.answer AS  'Month of Surgery:',
q3.answer AS  'Year of Surgery:',
q4.answer AS  'Current Brand:',
q5.answer AS  'Degree of Satisfaction:'
FROM (
    SELECT DISTINCT ordID, ordName, ordLastName
    FROM orders
)o
LEFT JOIN (
    SELECT cs.order_id, a.answer
    FROM cart_survey cs
    LEFT JOIN survey_answers a ON cs.answer_id = a.id
    WHERE cs.question_id =18
)q1 ON o.ordID = q1.order_id
LEFT JOIN (
    SELECT cs.order_id, a.answer
    FROM cart_survey cs
    LEFT JOIN survey_answers a ON cs.answer_id = a.id
    WHERE cs.question_id =19
)q2 ON o.ordID = q2.order_id
LEFT JOIN (
    SELECT cs.order_id, a.answer
    FROM cart_survey cs
    LEFT JOIN survey_answers a ON cs.answer_id = a.id
    WHERE cs.question_id =20
)q3 ON o.ordID = q3.order_id
LEFT JOIN (
    SELECT cs.order_id, a.answer
    FROM cart_survey cs
    LEFT JOIN survey_answers a ON cs.answer_id = a.id
    WHERE cs.question_id =21
)q4 ON o.ordID = q4.order_id
LEFT JOIN (
    SELECT cs.order_id, a.answer
    FROM cart_survey cs
    LEFT JOIN survey_answers a ON cs.answer_id = a.id
    WHERE cs.question_id =22
)q5 ON o.ordID = q5.order_id
0 голосов
/ 15 октября 2010

Это версия MSSQL

select o.*, q1.[Type of Surgery:], q2.[Month of Surgery:], q3.[Year of surgery:]
    , q4.[Current Ostomy System Brand:]
    , q5.[Degree of Satisfaction with the fit and comfort of your Current Ostomy System:]
from (
    select distinct ordID, ordName + ' ' + ordLastName as [name] from dbo.Orders
) o
left join (
    select *, a.[Answer] as [Type of Surgery:] from cart_survey cs
    left join dbo.survey_answers a on cs.answer_id = a.id
    where cs.question_id = 1
) q1 on o.ordID = q1.[order_id]
left join (
    select *, a.[Answer] as [Month of Surgery:] from cart_survey cs
    left join dbo.survey_answers a on cs.answer_id = a.id
    where cs.question_id = 2
) q2 on o.ordID = q2.[order_id]
left join (
    select *, a.[Answer] as [Year of surgery:] from cart_survey cs
    left join dbo.survey_answers a on cs.answer_id = a.id
    where cs.question_id = 3
) q3 on o.ordID = q3.[order_id]
left join (
    select *, a.[Answer] as [Current Brand:] from cart_survey cs
    left join dbo.survey_answers a on cs.answer_id = a.id
    where cs.question_id = 4
) q4 on o.ordID = q4.[order_id]
left join (
    select *, a.[Answer] as [Degree of Satisfaction:] from cart_survey cs
    left join dbo.survey_answers a on cs.answer_id = a.id
    where cs.question_id = 5
) q5 on o.ordID = q5.[order_id]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...