2010-06-17 26 views
5

Her soru için bir sütun ve yanıt veren her kişi için bir satır içeren bir anket veritabanım var. Her soru Şimdi, her yanıt numarası için bir kolon ile, söz konusu her bir satır olarak sonuçları göstermek gerekir 3.SQL'de, bir sütundaki değerlerin sayısını nasıl sayabilirim ve sonra sütun satır haline gelsin diye nasıl döndürürüm?

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

1 arasında bir değer ile cevap ve her sütunundaki değer sayısı ediliyor Bu cevabı kullanan cevapların Son olarak, toplam skoru hesaplamam gerekiyor, bu da 1'in artı iki katın iki katı artı üç katın üç katı kadar olan sayıdır.

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

Set-tabanlı SQL'de bunu yapmanın bir yolu var mı? SQL'de C# veya imleçlerdeki döngüler kullanarak nasıl yapılacağını biliyorum, ancak bunu imleçleri desteklemeyen bir raporlama aracında çalışmayı deniyorum.

+0

Eğer herhangi bir RDBMS yapmak istiyor musunuz? –

+0

Kimlik anahtarları bireysel soruları mı yoksa bireysel kullanıcıları mı temsil ediyor? – Kenneth

+0

hangi raporlama aracı –

cevap

3

Bu sorduğun şeyi vereceğim: Sorularınız ve hatta potansiyel cevaplar ekledikçe bu hızla balon edeceğini olsa

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 

unutmayın. Biraz normalleştirdiyseniz ve bir yanıtı bir tablonun sütunlarına yerleştirmek yerine, bir soru kodu veya kimliği ile her cevap için bir satır içeren bir Yanıtlar tablosuna sahip olsaydınız daha iyi olabilirsiniz. Varlık-değer çifti tasarımına biraz benzemeye başlıyor, ama bence burada yararlı olacak kadar farklı.

+0

Bu mantıklı, teşekkürler! –

+0

Bu kodun bir Grup ifadesine ihtiyacı yok mu? Verileri saklamak için önerilen normalizasyona katılıyorum, ancak analiz edildikten sonra, çoğu istatistik yazılım paketi için en azından bir e-tablo tipi görünümü yazmanız gerekiyor. Son ifadede yanlış olduğun için sevinirim ... –

+0

@ ran2 - Tüm tabloyu topladığı için GROUP BY'ye ihtiyaç duymaz. Normalleştirildikten sonra, aynı verileri benzer bir sorgu kullanarak, ancak tüm UNION'lar olmadan alabilirsiniz. Ayrıca PIVOT'u da kullanabilirsiniz. –

1

Ayrıca, istediğiniz şeyi elde etmek için SQL 2005'in döndürme işlevlerinden de yararlanabilirsiniz. Bu şekilde çapraz tablolamada yaptığınız gibi herhangi bir soruyu sabit kodlamanız gerekmez. Kaynak tabloyu "mytable" olarak adlandırdığımı ve okunabilirlik için ortak tablo ifadelerini kullandığımı ancak alt sorguları da kullanabileceğinizi unutmayın. Sorgu basittir dökümünü istemiyorsanız

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 

Not:

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