2010-06-17 33 views
5

Tôi có một cơ sở dữ liệu khảo sát với một cột cho mỗi câu hỏi và một hàng cho mỗi người trả lời. Mỗi câu hỏi được trả lời với một giá trị từ 1 đến 3.Trong SQL, làm thế nào tôi có thể đếm số lượng giá trị trong một cột và sau đó xoay nó để cột trở thành hàng?

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

Bây giờ, tôi cần phải hiển thị kết quả như một hàng cho mỗi câu hỏi, với một cột cho mỗi số phản ứng, và giá trị trong mỗi cột là số các câu trả lời đã sử dụng câu trả lời đó. Cuối cùng, tôi cần phải tính toán tổng số điểm, đó là số của 1 cộng với hai lần số lượng của 2 cộng với ba lần số lượng của threes.

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

Có cách nào để thực hiện điều này trong SQL dựa trên cơ sở không? Tôi biết làm thế nào để làm điều đó bằng cách sử dụng vòng trong C# hoặc con trỏ trong SQL, nhưng tôi đang cố gắng để làm cho nó hoạt động trong một công cụ báo cáo không hỗ trợ con trỏ.

+0

Bạn có muốn làm điều này trong bất kỳ RDBMS cụ thể không? –

+0

Các phím id có đại diện cho các câu hỏi riêng lẻ hoặc người dùng cá nhân không? – Kenneth

+0

công cụ báo cáo nào –

Trả lời

3

này sẽ cung cấp cho bạn những gì bạn đang yêu cầu cho:

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 

Cũng nên lưu ý rằng điều này sẽ nhanh chóng phình khi bạn thêm câu hỏi hoặc thậm chí câu trả lời tiềm năng. Bạn có thể tốt hơn nhiều nếu bạn chuẩn hóa một chút và có một bảng trả lời với một hàng cho mỗi câu trả lời với một mã câu hỏi hoặc id, thay vì đặt chúng trên các cột trong một bảng. Nó bắt đầu trông hơi giống thiết kế cặp giá trị thực thể, nhưng tôi nghĩ rằng nó đủ khác nhau để có ích ở đây.

+0

Điều đó có ý nghĩa, cảm ơn! –

+0

Mã này có cần một câu lệnh theo Nhóm không? Để lưu trữ dữ liệu - tôi đồng ý với việc chuẩn hóa được đề xuất, nhưng một khi nói đến việc phân tích bạn phải viết ít nhất một kiểu xem bảng tính cho hầu hết các gói phần mềm thống kê. Tôi muốn được chứng minh sai trên tuyên bố cuối cùng ... –

+0

@ ran2 - Nó không cần một GROUP BY bởi vì nó tổng hợp trên toàn bộ bảng. Khi đã chuẩn hóa, bạn có thể nhận được cùng một dữ liệu này bằng một truy vấn tương tự, nhưng không có tất cả các UNION. Bạn cũng có thể sử dụng PIVOT. –

1

Bạn cũng có thể tận dụng các chức năng xoay vòng của SQL 2005 để đạt được những gì bạn muốn. Bằng cách này, bạn không cần phải viết mã cứng bất kỳ câu hỏi nào khi bạn làm trong bảng chéo. Lưu ý rằng tôi gọi là bảng nguồn "mytable" và tôi đã sử dụng các biểu thức bảng chung cho khả năng đọc nhưng bạn cũng có thể sử dụng các truy vấn phụ.

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 

Lưu ý nếu bạn không muốn sự phân hủy các truy vấn đơn giản:

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 
Các vấn đề liên quan