Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

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

यह कम से कम आपके द्वारा मांगे गए के करीब होना चाहिए। इसे पिवट में बदलने के लिए डायनेमिक 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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. क्या एक एकल SQL सर्वर कथन परमाणु और सुसंगत है?

  2. संग्रहीत प्रक्रिया के लिए डेटाटाइम पास करें

  3. ऑर्डर बाय क्लॉज के बिना SQL सेलेक्ट स्टेटमेंट का ऑर्डर

  4. व्युत्पन्न कॉलम में स्ट्रिंग दिनांक आयात करें

  5. SQL सर्वर त्रुटि 111:"... किसी क्वेरी बैच में पहला कथन होना चाहिए"