Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Kueri Tab Silang SQL

SELECT MIN(ro.OptionText) RowOptionText, MIN(co.OptionText) RowOptionText, COUNT(ca.AnswerID) AnswerCount
FROM tblQuestions rq 
CROSS JOIN tblQuestions cq 
JOIN tblOptions ro ON rq.QuestionID = ro.QuestionID
JOIN tblOptions co ON cq.QuestionID = co.QuestionID
LEFT JOIN tblAnswers ra ON ra.OptionID = ro.OptionID
LEFT JOIN tblAnswers ca ON ca.OptionID = co.OptionID AND ca.UserID = ra.UserID
WHERE rq.questionText = 'Gender'
AND cq.questionText = 'How happy are you?'
GROUP BY ro.OptionID, co.OptionID
ORDER BY ro.OptionID, co.OptionID

Ini harus setidaknya mendekati apa yang Anda minta. Mengubahnya menjadi pivot akan membutuhkan SQL dinamis karena SQL Server mengharuskan Anda menentukan nilai aktual yang akan diputar menjadi kolom.

Kami menggabungkan pertanyaan silang dan membatasi hasil dari masing-masing referensi pertanyaan tersebut ke pertanyaan tunggal untuk nilai baris dan nilai kolom masing-masing. Kemudian kami menggabungkan nilai opsi ke referensi pertanyaan masing-masing. Kami menggunakan LEFT JOIN untuk jawaban jika pengguna tidak menanggapi semua pertanyaan. Dan kami menggabungkan jawaban dengan UserID sehingga kami mencocokkan pertanyaan baris dan kolom pertanyaan untuk setiap pengguna. MIN pada teks opsi adalah karena kami mengelompokkan dan mengurutkan berdasarkan ID Opsi agar sesuai dengan urutan yang ditampilkan.

EDIT:Inilah SQLFiddle

Untuk apa nilainya, kueri Anda rumit karena Anda menggunakan pola desain Entity-Attribute-Value. Beberapa ahli SQL Server menganggap pola itu bermasalah dan harus dihindari jika memungkinkan. Misalnya lihat https:// /www.simple-talk.com/sql/t-sql-programming/avoiding-the-eav-of-destruction/ .

EDIT 2:Karena Anda menerima jawaban saya, inilah solusi pivot SQL dinamis :) SQLFiddle

DECLARE @SqlCmd NVARCHAR(MAX)

SELECT @SqlCmd = N'SELECT RowOptionText, ' + STUFF(
    (SELECT ', ' + QUOTENAME(o.OptionID) + ' AS ' + QUOTENAME(o.OptionText)
    FROM tblOptions o 
    WHERE o.QuestionID = cq.QuestionID
    FOR XML PATH ('')), 1, 2, '') + ', RowTotal AS [Row Total]
FROM (
    SELECT ro.OptionID RowOptionID, ro.OptionText RowOptionText, co.OptionID ColOptionID,
       ca.UserID, COUNT(ca.UserID) OVER (PARTITION BY ra.OptionID) AS RowTotal
    FROM tblOptions ro
    JOIN tblOptions co ON ro.QuestionID = ' + CAST(rq.QuestionID AS VARCHAR(10)) + 
    ' AND co.QuestionID = ' + CAST(cq.QuestionID AS VARCHAR(10)) + '
    LEFT JOIN tblAnswers ra ON ra.OptionID = ro.OptionID
    LEFT JOIN tblAnswers ca ON ca.OptionID = co.OptionID AND ca.UserID = ra.UserID
    UNION ALL 
    SELECT 999999, ''Column Total'' RowOptionText, co.OptionID ColOptionID,
       ca.UserID, COUNT(ca.UserID) OVER () AS RowTotal
    FROM tblOptions ro
    JOIN tblOptions co ON ro.QuestionID = ' + CAST(rq.QuestionID AS VARCHAR(10)) + 
    ' AND co.QuestionID = ' + CAST(cq.QuestionID AS VARCHAR(10)) + '
    LEFT JOIN tblAnswers ra ON ra.OptionID = ro.OptionID
    LEFT JOIN tblAnswers ca ON ca.OptionID = co.OptionID AND ca.UserID = ra.UserID
) t
PIVOT (COUNT(UserID) FOR ColOptionID IN (' + STUFF(
    (SELECT ', ' + QUOTENAME(o.OptionID) 
    FROM tblOptions o 
    WHERE o.QuestionID = cq.QuestionID
    FOR XML PATH ('')), 1, 2, '') + ')) p
ORDER BY RowOptionID'
FROM tblQuestions rq 
CROSS JOIN tblQuestions cq 
WHERE rq.questionText = 'Gender' 
AND cq.questionText = 'How happy are you?'

EXEC sp_executesql @SqlCmd


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Menghubungkan ke SQL Server Instance dengan menggunakan Windows Authentication atau SQL Server Authentication - Tutorial SQL Server / T-SQL Bagian 3

  2. Tabel vs Kinerja Tabel Temp

  3. Gabungkan beberapa record menjadi satu baris dalam sebuah tabel

  4. Tambahkan Kolom pada SQL Server di Tempat Tertentu?

  5. SQL - Jumlah persentase