2013-09-02 2 views
2

У меня есть коллекция из SQL Server таблиц, содержащих информацию обследований, и я хотел бы запустить запрос, который имеет одну строку для каждого опроса и по одному столбцу для каждого ответа.Запрос на длинный запрос настройки

Структура настройки следующим образом:

ResponseHeader: 
ID (record for each survey) 

Responses: 
ID 
responseHeaderID 
questionID 
answerItemsID 

AnswerItems: 
ID (This is the value needed in each answer column) 
answerText 

Ниже приведен запрос, который я придумал:

SELECT ResponseHeader.id 
    , ResponseHeader.YOS 
    , ResponseHeader.rankID 
    , ResponseHeaderunitID 
    , ResponseHeader.age 
    , ResponseHeader.gender 
    , MAX(CASE WHEN Responses.questionID = 42 THEN AnswerItems.id END) 
    , MAX(CASE WHEN Responses.questionID = 43 THEN AnswerItems.id END) 
    , MAX(CASE WHEN Responses.questionID = 44 THEN AnswerItems.id END) 
    , --.....there are 79 of these lines in the query, one for each question (Responses.questionID) 
     MAX(CASE WHEN Responses.questionID = 48 THEN AnswerItems.id END) 
    , MAX(CASE WHEN Responses.questionID = 48 THEN AnswerItems.id END) 
    , MAX(CASE WHEN Responses.questionID = 50 THEN AnswerItems.id END) 
    , MAX(CASE WHEN Responses.questionID = 49 THEN AnswerItems.id END) 
FROM ResponseHeader 
LEFT OUTER JOIN Responses ON ResponseHeader.id = Responses.responseHeaderID 
LEFT OUTER JOIN AnswerItems ON Responses.answerItemsID = AnswerItems.id 
WHERE completed = 1 
GROUP BY 
     ResponseHeader.id 
    , YOS 
    , rankID 
    , unitID 
    , age 
    , gender 
ORDER BY ResponseHeader.id; 

Это возвращает правильный набор результатов, но это занимает 18 секунд выполнить в Query Analyzer. Он возвращает 4592 строки и имеет 85 столбцов. К сожалению, он достигает предела IIS, поэтому считается, что он занимает много времени, чтобы использовать его на классической странице ASP. Увеличение предела буфера не является вариантом для задания. Я не уверен, как получить эту информацию по-другому.

Я читал о pivot-запросах, но не понял их. Есть ли способ получить мои результаты, используя этот или любой другой метод быстрее?

+1

@ Mat41. , , Я бы переписал это как «сводный» запрос, чтобы убедиться, что это повышает производительность. –

+0

Линии, о которых вы говорите, дают мне столбец для каждого ответа. Я написал этот запрос, поэтому для каждого ответа была строка, которая дала мне 320000 строк. Это был единственный способ выяснить, как достичь ряда для каждого опроса (ResponseHeader.id) и столбца для каждого ответа. @Gordon Я читал об этих сводных запросах, но не понимаю их понимания, не могли бы вы мне хоть немного помочь? – Mat41

+2

@ Mat41. , , Вы должны отредактировать запрос, чтобы включить псевдонимы таблиц, поэтому кто-то, читающий вопрос, имеет некоторое представление о том, откуда идут столбцы. –

ответ

3

попробовать что-то вроде этого -

DECLARE @Responses TABLE (responseHeaderID INT, questionID INT, answerItemsID INT) 
DECLARE @ResponseHeader TABLE (id INT, YOS INT, rankID INT, unitID INT, age INT, gender CHAR(1), completed BIT) 

SELECT * 
FROM (
    SELECT DISTINCT 
      rh.id 
     , rh.YOS 
     , rh.rankID 
     , rh.unitID 
     , rh.age 
     , rh.gender 
    FROM @ResponseHeader rh 
    WHERE completed = 1 
) rh 
LEFT JOIN (
    SELECT * 
    FROM (
     SELECT 
       r.responseHeaderID 
      , r.questionID 
      , r.answerItemsID 
     FROM @Responses r 
    ) t 
    PIVOT 
    (
     MAX(answerItemsID) FOR questionID IN ([42], [43], [44], [48], [50], [49]) 
    ) p 
) t2 ON rh.id = t2.responseHeaderID 
ORDER BY rh.id 

Выход -

+0

Мне нужно узнать об этом, выглядит сложным ... QA говорит мне, что есть четыре проблемы. Первые два относятся к «а». и 'r.' в этой строке'MAX (a.id) FOR r.questionID IN 'it says' не совпадает с именем таблицы или псевдонимом, используемым в запросе. Он говорит, что «t.responseHeaderID» не может быть привязан, и «responseHeaderID» был указан несколько раз для «cte» – Mat41

+0

. Попробуйте обновленный ответ. – Devart

+0

Да, это работает очень хорошо, спасибо! Ничего себе, мой первоначальный запрос занял 18 секунд. Когда я размещаю все 85 элементов в разделе «[42], [43], [44], [48], [50], [49]», используя ваш сводный запрос, он занимает менее 1 секунды. Я поражен. Один вопрос, почему значения questionID должны быть окружены []? Обычно, когда я говорю WHERE IN, допускается строка с разделителями-ограничителями. Почему это невозможно использовать в этой ситуации, из-за «FOR» я предполагаю? – Mat41

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