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
यह कम से कम आपके द्वारा मांगे गए के करीब होना चाहिए। इसे पिवट में बदलने के लिए डायनेमिक SQL की आवश्यकता होगी क्योंकि SQL सर्वर के लिए आपको वास्तविक मान निर्दिष्ट करने की आवश्यकता होती है जिसे एक कॉलम में पिवोट किया जाएगा।
हम प्रश्नों में शामिल होते हैं और उन प्रत्येक प्रश्न संदर्भों के परिणामों को क्रमशः पंक्ति मानों और स्तंभ मानों के लिए एकल प्रश्न तक सीमित करते हैं। फिर हम विकल्प मानों को संबंधित प्रश्न संदर्भ से जोड़ते हैं। यदि उपयोगकर्ता ने सभी प्रश्नों का उत्तर नहीं दिया तो हम उत्तर के लिए LEFT JOIN का उपयोग करते हैं। और हम UserID द्वारा उत्तरों में शामिल हो जाते हैं ताकि हम प्रत्येक उपयोगकर्ता के लिए पंक्ति प्रश्न और स्तंभ प्रश्न का मिलान कर सकें। विकल्प टेक्स्ट पर MIN इसलिए है क्योंकि हमने आपके दिखाए गए अनुक्रमण से मेल खाने के लिए OptionID द्वारा समूहीकृत और आदेशित किया है।
संपादित करें:यहां एक SQLFiddle है।
इसके लायक क्या है, आपकी क्वेरी जटिल है क्योंकि आप एंटिटी-एट्रिब्यूट-वैल्यू डिज़ाइन पैटर्न का उपयोग कर रहे हैं। काफी कुछ SQL सर्वर विशेषज्ञ उस पैटर्न को समस्याग्रस्त मानते हैं और यदि संभव हो तो इससे बचा जा सकता है। उदाहरण के लिए देखें https:/ /www.simple-talk.com/sql/t-sql-programming/avoiding-the-eav-of-destruction/ ।
संपादित करें 2:चूंकि आपने मेरा उत्तर स्वीकार कर लिया है, यहां गतिशील SQL धुरी समाधान है :) एसक्यूएलफ़िल्ड
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