6

質問ごとに 1 列、回答者ごとに 1 行の調査データベースがあります。各質問は、1 から 3 までの値で回答されます。

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

ここで、結果を質問ごとに 1 行として表示する必要があります。列には各回答番号があり、各列の値はその回答を使用した回答の数です。最後に、合計スコアを計算する必要があります。これは、1 の数と 2 の数の 2 倍と 3 の数の 3 倍です。

Question  1    2    3    Total
--------  --   --   --   -----
Quality?  0    2    2    10
Speed?    2    1    1    7

セットベースの SQL でこれを行う方法はありますか? C# のループまたは SQL のカーソルを使用してそれを行う方法は知っていますが、カーソルをサポートしていないレポート ツールで機能させようとしています。

4

2 に答える 2

4

これにより、あなたが求めているものが得られます:

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 つのテーブルに列として配置するのではなく、少し正規化し、質問コードまたは ID を含む各回答の行を含む Answers テーブルを作成すると、はるかにうまくいく可能性があります。エンティティと値のペアのデザインに少し似ているように見えますが、ここで役立つほど十分に異なっていると思います。

于 2010-06-17T18:05:26.547 に答える
1

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
于 2010-06-17T19:31:37.537 に答える