В SQL как подсчитать количество значений в столбце, а затем повернуть его, чтобы столбец стал строкой? - PullRequest
5 голосов
/ 17 июня 2010

У меня есть база данных опроса с одним столбцом для каждого вопроса и одной строкой для каждого отвечающего.Ответы на каждый вопрос имеют значение от 1 до 3.

Id    Quality?  Speed?
--    -------   -----
1     3         1
2     2         1
3     2         3
4     3         2

Теперь мне нужно отобразить результаты в виде одной строки на вопрос, со столбцом для каждого номера ответа и значением в каждом столбцеколичество ответов, которые использовали этот ответ.Наконец, мне нужно вычислить общий балл, который представляет собой число 1 плюс два, умноженное на 2, плюс троекратное количество троек.на основе SQL?Я знаю, как это сделать, используя циклы в C # или курсоры в SQL, но я пытаюсь заставить его работать в инструменте отчетности, который не поддерживает курсоры.

Ответы [ 2 ]

3 голосов
/ 17 июня 2010

Это даст вам то, что вы просите:

SELECT
    'quality' AS question,
    SUM(CASE WHEN quality = 1 THEN 1 ELSE 0 END) AS [1],
    SUM(CASE WHEN quality = 2 THEN 1 ELSE 0 END) AS [2],
    SUM(CASE WHEN quality = 3 THEN 1 ELSE 0 END) AS [3],
    SUM(quality)
FROM
    dbo.Answers
UNION ALL
SELECT
    'speed' AS question,
    SUM(CASE WHEN speed = 1 THEN 1 ELSE 0 END) AS [1],
    SUM(CASE WHEN speed = 2 THEN 1 ELSE 0 END) AS [2],
    SUM(CASE WHEN speed = 3 THEN 1 ELSE 0 END) AS [3],
    SUM(speed)
FROM
    dbo.Answers

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

1 голос
/ 17 июня 2010

Вы также можете использовать функции поворота SQL 2005 для достижения желаемого.Таким образом, вам не нужно жестко задавать какие-либо вопросы, как в кросс-табуляции.Обратите внимание, что я назвал исходную таблицу «mytable», и для удобства чтения я использовал общие табличные выражения, но вы также можете использовать подзапросы.

WITH unpivoted AS (
    SELECT id, value, question
    FROM mytable a
    UNPIVOT (value FOR question IN (quality,speed) ) p
)
,counts AS (
    SELECT question, value, count(*) AS counts
    FROM unpivoted
    GROUP BY question, value
)
, repivoted AS (
    SELECT question, counts, [1], [2], [3]
    FROM counts
    PIVOT (count(value) FOR value IN ([1],[2],[3])) p 
)
SELECT question, sum(counts*[1]) AS [1], sum(counts*[2]) AS [2], sum(counts*[3]) AS [3]
    ,sum(counts*[1]) + 2*sum(counts*[2]) + 3*sum(counts*[3]) AS Total
FROM repivoted
GROUP BY question

Обратите внимание: если вы не хотите разбивать, запрос проще:

WITH unpivoted AS (
    SELECT id, value, question
    FROM mytable a
    UNPIVOT (value FOR question IN (quality,speed) ) p
)
, totals AS (
    SELECT question, value, count(value)*value AS score
    FROM unpivoted
    GROUP BY question, value
)
SELECT question, sum(score) AS score
FROM totals
GROUP BY question
...