2017-03-08 12 views
1

SQL Server 2008を使用しており、列を個々の行に分割するクエリを作成しようとしています。私はカウントデータを引き出し、それを個々の得点に変換する必要があります。SQL:UN-PIVOTおよび個別スコア別

例:
5学生は「常に」と答えと「いつも」= 3ポイントの答え。
4人の学生が「普通」と答え、「通常」= 2点の回答

「常時」という名前のフィールドが5つのフィールドと「通常」という名前のフィールドの代わりに4とカウントされます'スコア'という3つの行と4行の5行の2つのフィールドを持つようになりました。

私はUNPIVOTを使用してクエリを開始しましたが、説明どおりにデータを分割しません。サンプルデータと私の望む結果を以下に掲載しました。どんな助けもありがとう。

Always = 3 points 
Usually = 2 points  
Sometimes = 1 points  
Never = 0 points 

サンプルデータ:

CREATE TABLE #TEST(QUESTION VARCHAR(15), STUDENT VARCHAR(15), STARTDATE DATE, ALWAYS INT, USUALLY INT, SOMETIMES INT, NEVER INT) 

INSERT #TEST(QUESTION, STUDENT, STARTDATE, ALWAYS, USUALLY, SOMETIMES, NEVER) 
VALUES 
('A','BOB','01/01/2016',2,1,1,2), 
('A','BOB','03/01/2016',3,1,1,0), 
('A','JIM','01/01/2016',2,1,2,0), 
('A','JIM','03/01/2016',4,1,0,0), 
('BB','BOB','03/01/2016',2,1,1,2), 
('BB','BOB','07/01/2016',3,1,1,0), 
('BB','JIM','03/01/2016',2,1,2,0), 
('BB','JIM','07/01/2016',4,1,0,0) 

問合せ:

WITH A AS (
    SELECT * 
    FROM #TEST 
    --WHERE 
    -- QUESTION = 'A' 
    --AND STUDENT IN ('BOB','JIM') 
    --AND STARTDATE = '2016-01-01' 
) 
SELECT QUESTION, STUDENT, STARTDATE, SCORE 
FROM 
    ( SELECT QUESTION, STUDENT, STARTDATE, ALWAYS, USUALLY, SOMETIMES, NEVER 
     FROM A 
    ) P 
UNPIVOT 
    (SCORE FOR Z IN (ALWAYS, USUALLY, SOMETIMES, NEVER) 
    ) AS unpvt 

期待される結果:第一のための2行

QUESTION|STUDENT|STARTDATE|SCORE| 
--------+-------+---------+-----+ 
A  |BOB |1/1/2016 |3 |--ALWAYS 
A  |BOB |1/1/2016 |3 |--ALWAYS 
A  |BOB |1/1/2016 |2 |--USUALLY 
A  |BOB |1/1/2016 |1 |--SOMETIMES 
A  |BOB |1/1/2016 |0 |--NEVER 
A  |BOB |1/1/2016 |0 |--NEVER 
A  |BOB |3/1/2016 |3 |--ALWAYS 
A  |BOB |3/1/2016 |3 |--ALWAYS 
A  |BOB |3/1/2016 |3 |--ALWAYS 
A  |BOB |3/1/2016 |2 |--USUALLY 
A  |BOB |3/1/2016 |1 |--SOMETIMES 

答えて

1

適用し、アドホック集計テーブル

Select A.Question 
     ,A.Student 
     ,A.StartDate 
     ,B.Score 
From #Test A 
Cross Apply (values (Always,3) 
        ,(Usually,2) 
        ,(Sometimes,1) 
        ,(Never,0) 
      ) B(Cnt,Score) 
Join (Select Top 100 N=Row_Number() Over (Order By Number) From master..spt_values) C 
    on (C.N <= B.Cnt) 
Where Student='Bob' and question ='A' 

戻り

Question Student StartDate Score 
A   BOB  2016-01-01 3 
A   BOB  2016-01-01 3 
A   BOB  2016-01-01 2 
A   BOB  2016-01-01 1 
A   BOB  2016-01-01 0 
A   BOB  2016-01-01 0 
A   BOB  2016-03-01 3 
A   BOB  2016-03-01 3 
A   BOB  2016-03-01 3 
A   BOB  2016-03-01 2 
A   BOB  2016-03-01 1 
+0

助けてくれてありがとう、あなたの提案は私のサンプルデータセットのために動作します。あなたはこれを説明することができますか?JOIN(選択トップ100 N = ROW_NUMBER()オーバー(注文番号から)マスター... spt_values) "?私はこのテーブルが使われたことを一度も見たことがなく、なぜそれを使用したのか、トップ100を選択したのか理解していません。 – JBritton

+1

@JBritton 100レコードのアドホック・タリー/これにより、レコードセットの「拡張」が可能になります。 –

+1

@JBrittonトップ100は任意の値でした。あなたが10の反応以上のものを見たことがないなら、それをトップ10にします。それはより大きな価値を持つ害はありません。サブクエリは1回解決されます –

0

管理不可能な数の列をピボット解除する場合は、通常はそれぞれ個別のクエリを作成し、UNION ALLと組み合わせて使用​​します。アンピボットするcross apply (values...)を使用CROSSの助けを借りて

SELECT Question, Student, StartDate, Always AS Score 
FROM #TEST 
WHERE ... 

UNION ALL 

SELECT Question, Student, StartDate, Usually AS Score 
FROM #TEST 
WHERE ... 
0

:ここ

は、一般的な考え方でありますあなたのデータ、1-9の数値表、およびポイント表を以下のようにすることができます:

with a as (
    select * 
    from #test 
    where question = 'A' 
    and student = 'bob' 
    --and student in ('bob','jim') 
    --and startdate = '20160101' 
) 
, points as (
    select Answer, Points 
    from (values ('Always',3),('Usually',2),('Sometimes',1),('Never',0) 
    ) p (Answer,Points) 
) 
, numbers as (
    select n 
    from (values(1),(2),(3),(4),(5),(6),(7),(8),(9) 
    ) t(n) 
) 
, unp as (
    select 
     a.question 
    , a.student 
    , StartDate=convert(varchar(10),a.startdate,120) 
    , x.AnswerCount 
    , x.Answer 
    from a 
    cross apply (
     values ([Always],'Always') 
     , ([Usually],'Usually') 
     , ([Sometimes],'Sometimes') 
     , ([Never],'Never') 
    ) x (AnswerCount,Answer) 
) 
select 
    unp.question 
    , unp.student 
    , unp.startdate 
    , score = p.points 
    , unp.answer 
    from unp 
    inner join numbers n on n.n<=unp.AnswerCount 
    inner join points p on unp.answer=p.answer 

rextesterデモ:http://rextester.com/GQCN45867

リターン:

+----------+---------+------------+-------+-----------+ 
| question | student | startdate | score | answer | 
+----------+---------+------------+-------+-----------+ 
| A  | bob  | 2016-01-01 |  3 | Always | 
| A  | bob  | 2016-01-01 |  3 | Always | 
| A  | bob  | 2016-01-01 |  2 | Usually | 
| A  | bob  | 2016-01-01 |  1 | Sometimes | 
| A  | bob  | 2016-01-01 |  0 | Never  | 
| A  | bob  | 2016-01-01 |  0 | Never  | 
| A  | bob  | 2016-01-03 |  3 | Always | 
| A  | bob  | 2016-01-03 |  3 | Always | 
| A  | bob  | 2016-01-03 |  3 | Always | 
| A  | bob  | 2016-01-03 |  2 | Usually | 
| A  | bob  | 2016-01-03 |  1 | Sometimes | 
+----------+---------+------------+-------+-----------+ 
関連する問題