Выделите строки в столбцы с группировкой - PullRequest
2 голосов
/ 09 марта 2012

У меня есть несколько таблиц:

     Exams 
     UserExams 
     UserExamQuestions 
     UserExamAnswers 
     Users 
     ExamQuestions 
     ExamQuestionAnswers

это я разработал

    select ue.DateStarted as 'Date Started', u.LastName as 'Lastname', 
    u.FirstName as 'Firstname', eq.Text as 'Question', eqa.Text as 'Answer',
    eqa.IsCorrect as 'Correct' from Exams e
    join UserExams ue on ue.ExamId = e.Id
    join UserExamQuestions ueq on ueq.UserExamId = ue.Id
    join UserExamAnswers uea on uea.UserExamQuestionId = ueq.Id
    join Users u on u.Id = ue.UserId
    join ExamQuestions eq on eq.Id = ueq.ExamQuestionId
    join ExamQuestionAnswers eqa on eqa.Id = uea.ExamQuestionAnswerId
    where e.Id = 10 and uea.IsSelected = 1
    order by u.LastName, u.FirstName

но, к сожалению, он возвращает данные нежелательным образом. Возвращенная строка выглядит так

    Date Started            Lastname  Firstname      Question             Answer         Correct
    2012-02-26 13:29:50.770 Somename  Somefirstname  Some question text?  Some answer   0
    2012-02-26 13:30:20.000 Othername Otherfirstname Some question text?  Some answer   0
    2012-02-26 15:10:10.212 Fifth     Fifthname      Some question text?  Other answer  1

Конечно, приведенный выше пример предназначен для трех пользователей, которые ответили на один вопрос с несколькими ответами. Выбранные данные в порядке, но мне нужно, чтобы это было так:

   Lastname  Firstname       [Some question text?] Correct
   Somename  Somefirstname   Some answer           0
   Othername Otherfirstname  Some answer           0
   Fifth     Fifthname       Other answer          1

Возможно ли это? Это не должно быть быстро. Делать это в коде будет больно ... Я пробовал сводку, но, во-первых, я не думаю, что понимаю это правильно, а во-вторых, я не хочу собирать данные.

Спасибо за помощь.

Ответы [ 2 ]

2 голосов
/ 09 марта 2012

Арион - ваш скрипт извлекает все вопросы в один столбец так:

   Lastname  Firstname       [Some question text?,Second question in same column?] Correct
   Somename  Somefirstname   Some answer                                           0
   Somename  Somefirstname   Answer to second question                             1
   Othername Otherfirstname  Some answer                                           0
   Othername Otherfirstname  Wrong answer to second question                       0
   Fifth     Fifthname       Other answer                                          1
   Fifth     Fifthname       Wrong answer to second question                       0

Что мне нужно, так это:

   Lastname  Firstname       [Some question text?] [Is Some question answer correct]  [Second question in same column?] [Is Second question in same column answer correct] 
   Somename  Somefirstname   Some answer           0                                  Answer to second question         1          
   Othername Otherfirstname  Some answer           0                                  Wrong answer to second question   0                             
   Fifth     Fifthname       Other answer          1                                  Wrong answer to second question   0
2 голосов
/ 09 марта 2012

Хорошо. Итак, я видел ваш ответ, и у меня есть предложение для вас. Вы действительно правы, когда говорите, что собираетесь сделать это с помощью оси.

Итак, сначала я упростил ваши данные для целей тестирования. Данные теста выглядят так:

CREATE TABLE Table1
(
    Lastname VARCHAR(100),  
    Firstname VARCHAR(100),
    Answer VARCHAR(100),
    Question VARCHAR(100),
    Correct BIT
)
INSERT INTO Table1
VALUES
  ('Somename','Somefirstname','Some answer','Some question text?',0),
  ('Somename','Somefirstname','Answer to second question','Second question in same column?',1),
  ('Othername','Otherfirstname','Some answer','Some question text?',0),
  ('Othername','Otherfirstname','Wrong answer to second question','Second question in same column?',0),
  ('Fifth','Fifthname','Other answer','Some question text?',1),
  ('Fifth','Fifthname','Wrong answer to second question','Second question in same column?',0)

Вам нужно получить уникальные столбцы для поворота. Как это:

DECLARE @Questions VARCHAR(MAX)
;WITH CTE
AS
(
  SELECT
    ROW_NUMBER() OVER(PARTITION BY Question ORDER BY Question) AS RowNbr,
    ROW_NUMBER() OVER(ORDER BY Question) AS OrderBy,
    Table1.Question
  FROM
    Table1
), CTE2
AS
(
  SELECT
    CTE.OrderBy AS OrderBy,
    1 AS SecondOrder,
    CTE.Question
  FROM
    CTE
  WHERE
    CTE.RowNbr=1
  UNION ALL
  SELECT
    CTE.OrderBy AS OrderBy,
    2 AS SecondOrder,
    'Is '+CTE.Question
  FROM
    CTE
  WHERE
    CTE.RowNbr=1
)
SELECT
  @Questions = COALESCE(@Questions + ','+QUOTENAME(Question),
                     QUOTENAME(Question))
FROM
  CTE2
ORDER BY
  CTE2.OrderBy,
  CTE2.SecondOrder
  • Первый ROW_NUMBER() OVER(PARTITION BY Question ORDER BY Question) - получить уникальные столбцы. Я буду использовать его позже с оператором where.

  • Второй ROW_NUMBER() OVER(ORDER BY Question) это заказать вопросы

  • * * * * * * * * * * * * * * * * * * * * SecondOrder, так что вы закажете вопрос перед тем, как задать вопрос "Есть".

  • * * * * * * * * * * * * * * * * * * * *

    1030 *.
  • @Questions = COALESCE(@Questions + ','+QUOTENAME(Question), .. Сводит столбцы в один varchar

Затем нам нужно создать динамический sql для pivot и в конце выполнить его. Как это:

DECLARE @query NVARCHAR(4000)=
N';WITH CTE
AS
(
  SELECT
    Table1.Lastname,
    Table1.Firstname,
    Table1.Answer,
    Table1.Question
  FROM
    Table1
  UNION ALL
  SELECT
    Table1.Lastname,
    Table1.Firstname,
    CAST(Table1.Correct AS VARCHAR(10)) AS Answer,
    ''Is ''+Table1.Question AS Question
  FROM
    Table1
)
SELECT
  *
FROM
(
  SELECT
    CTE.Lastname,
    CTE.Firstname,
    CTE.Answer,
    CTE.Question
  FROM
    CTE
) AS p
PIVOT
(
    MAX(Answer)
    FOR Question IN ('+@Questions+')
) AS pvt'
EXECUTE(@query)
  • Тогда нам нужно UNION ALL вопросы с вопросами «Есть»

  • Столбец Correct приведен к VARCHAR, поскольку UNION ALL и сводная диаграмма не допускают разные типы данных

  • Мы будем использовать MAX агрегат, чтобы получить ответ, который нам нужен. Это связано с тем, что сводная таблица требует использования агрегата.

  • FOR Question IN ('+@Questions+') - это столбцы, которые мы констатировали в приведенном выше запросе.

Вы можете увидеть результат и данные примера здесь

Надеюсь, это поможет вам

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...