2015-10-13 30 views
5

Mam tabeli, gdzie każda kolumna jest pytanie i wiersze są odpowiedzi, które mogą przyjmować wartości od 1 do 4TSQL zdarzenia liczyć w wielu kolumnach

Jaki jest najbardziej efektywny sposób obliczyć wystąpień każdego odpowiedź na pytanie?

tabela Wejście

q1 q2 q3 
1 3 1 
2 1 4 
1 2 1 

Pożądany tabela wyjściowa

answer q1 q2 q3 

    1 2 0 2 
    2 1 1 0 
    3 0 1 0 
    4 0 0 1 

Dotychczas przyjechałem do następujących (Q3 pytanie), ale to tylko dla jednego pytania

CREATE TABLE #t 
    (
    answer int 
) 
insert into #t (answer) values (1) 
insert into #t (answer) values (2) 
insert into #t (answer) values (3) 
insert into #t (answer) values (4) 

select * into #q3 from (select q3 as q3,count(*) as occurenceq3 
        from [table] 
        group by q3) as x 

select t.answer,tb.occurenceq3 as occurenceq3 
from #t t left join #q3 tb on t.answer=tb.Q3 

drop table #q3 
drop table #t 
+0

Prawdopodobnie UNPIVOT następnie pivot. – shawnt00

Odpowiedz

4
select answer, q1, q2, q3 
from 
    q 
    unpivot (answer for q in (q1, q2, q3)) as upvt 
    pivot (count(q) for q in (q1, q2, q3)) as pvt 

Popełniłem błąd pierwszego próbowania count(*), ale myślę, że ma to sens, że agregacja musi być jawnie na kolumnie, która jest obrócona, chociaż myślę, że byłyby logicznie równoważne.

+0

hmm nie kompiluje się: niepoprawna składnia w pobliżu "*". – user2418209

+0

Może nie można odwoływać się do katalogu tabeli podstawowej. Próbowałem uruchomić to na SQL Fiddle, ale strona działa dziwnie jak zwykle. – shawnt00

+0

Jeśli wrócisz do oryginalnej publikacji i zastąpisz count (*) liczbą (q), zapytanie zadziała. –

1

To powinno działać: -

CREATE TABLE #question (q1 int, q2 int, q3 int) 
INSERT INTO #question 
VALUES 
(1,3,1), 
(2,1,4), 
(1,2,1); 

--unpivot to start with 
WITH 
UNPIVOTED AS 
(
SELECT * 
FROM 
    (SELECT q1,q2,q3 
    FROM #question) p 
UNPIVOT 
    (answer FOR question in (q1,q2,q3)) AS unpvt 
) 

--Then pivot 
SELECT * FROM 
(SELECT answer, question FROM unpivoted) p 
PIVOT 
(
COUNT(question) 
FOR question IN (q1,q2,q3) 
) as pvt 
0

Jeśli chcesz najbardziej efektywny sposób, chciałbym zaproponować wprowadzenie indeksu na każdej z „Q” kolumn i uruchomienie kwerendy jako:

select a.answer, 
     (select count(*) from #question q where q.q1 = a.answer) as q1, 
     (select count(*) from #question q where q.q2 = a.answer) as q2, 
     (select count(*) from #question q where q.q3 = a.answer) as q3 
from (select 1 as answer union all select 2 union all select 3 union all select 4 
    ) a; 

To zasadniczo wykorzystuje indeksy do zliczania wartości i powinno być dość szybkie, szybsze niż agregowanie wszystkich wyników niepodzielonych.

0

To zadziała

select t1.dis, 
q1=(select count(q1) from CountAnswers where q1=t1.dis), 
q2=(select count(q2) from countAnswers where q2=t1.dis), 
q3=(select count(q3) from countAnswers where q3=t1.dis) 
from (select dis from(select q1 as dis from CountAnswers union select q2 as dis from CountAnswers union select q3 as dis from CountAnswers)mytab)t1;