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

SQL:प्रत्येक व्यक्ति के लिए सबसे सामान्य मान लौटाना

प्रारंभिक टिप्पणी

कृपया स्पष्ट जॉइन नोटेशन का उपयोग करना सीखें, न कि पुराना (पूर्व-1992) अंतर्निहित जॉइन नोटेशन।

पुरानी शैली:

SELECT transactionTable.rating as MostCommonRating 
FROM personTable, transactionTable 
WHERE personTable.transactionid = transactionTable.transactionid 
AND personTable.personid = 1
GROUP BY transactionTable.rating 
ORDER BY COUNT(transactionTable.rating) desc 
LIMIT 1

पसंदीदा शैली:

SELECT transactionTable.rating AS MostCommonRating 
  FROM personTable
  JOIN transactionTable 
    ON personTable.transactionid = transactionTable.transactionid 
 WHERE personTable.personid = 1
 GROUP BY transactionTable.rating 
 ORDER BY COUNT(transactionTable.rating) desc 
 LIMIT 1

प्रत्येक जॉइन के लिए आपको एक ON शर्त की आवश्यकता होती है।

साथ ही, personID डेटा में मान स्ट्रिंग हैं, संख्या नहीं, इसलिए आपको लिखना होगा

 WHERE personTable.personid = "Ben"

उदाहरण के लिए, क्वेरी को दिखाए गए टेबल पर काम करने के लिए।

मुख्य उत्तर

आप एक समुच्चय का योग खोजना चाहते हैं:इस मामले में, अधिकतम संख्या। तो, किसी भी सामान्य समाधान में MAX और COUNT दोनों शामिल होंगे। आप MAX को सीधे COUNT पर लागू नहीं कर सकते, लेकिन आप एक उप-क्वेरी से उस कॉलम पर MAX लागू कर सकते हैं जहां कॉलम COUNT होता है।

टेस्ट-ड्रिवेन क्वेरी डिज़ाइन — TDQD का उपयोग करके क्वेरी बनाएँ।

व्यक्ति और लेन-देन रेटिंग चुनें

SELECT p.PersonID, t.Rating, t.TransactionID
  FROM PersonTable AS p
  JOIN TransactionTable AS t
    ON p.TransactionID = t.TransactionID

व्यक्ति, रेटिंग, और रेटिंग की घटनाओं की संख्या चुनें

SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
  FROM PersonTable AS p
  JOIN TransactionTable AS t
    ON p.TransactionID = t.TransactionID
 GROUP BY p.PersonID, t.Rating

यह परिणाम एक उप-क्वेरी बन जाएगा।

जानें कि व्यक्ति को कितनी बार कोई रेटिंग मिली है

SELECT s.PersonID, MAX(s.RatingCount)
  FROM (SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
          FROM PersonTable AS p
          JOIN TransactionTable AS t
            ON p.TransactionID = t.TransactionID
         GROUP BY p.PersonID, t.Rating
       ) AS s
 GROUP BY s.PersonID

अब हम जानते हैं कि प्रत्येक व्यक्ति के लिए अधिकतम संख्या कौन सी है।

आवश्यक परिणाम

परिणाम प्राप्त करने के लिए, हमें उप-क्वेरी से उन पंक्तियों का चयन करना होगा जिनकी अधिकतम संख्या है। ध्यान दें कि अगर किसी के पास 2 अच्छी और 2 खराब रेटिंग हैं (और 2 उस व्यक्ति के लिए एक ही प्रकार की रेटिंग की अधिकतम संख्या है), तो उस व्यक्ति के लिए दो रिकॉर्ड दिखाए जाएंगे।

SELECT s.PersonID, s.Rating
  FROM (SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
          FROM PersonTable AS p
          JOIN TransactionTable AS t
            ON p.TransactionID = t.TransactionID
         GROUP BY p.PersonID, t.Rating
       ) AS s
  JOIN (SELECT s.PersonID, MAX(s.RatingCount) AS MaxRatingCount
          FROM (SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
                  FROM PersonTable AS p
                  JOIN TransactionTable AS t
                    ON p.TransactionID = t.TransactionID
                 GROUP BY p.PersonID, t.Rating
               ) AS s
         GROUP BY s.PersonID
       ) AS m
    ON s.PersonID = m.PersonID AND s.RatingCount = m.MaxRatingCount

यदि आप वास्तविक रेटिंग गणना भी चाहते हैं, तो वह आसानी से चुनी जाती है।

यह SQL का काफी जटिल टुकड़ा है। मुझे इसे खरोंच से लिखने की कोशिश करने से नफरत होगी। वास्तव में, मैं शायद परेशान नहीं होता; जैसा कि दिखाया गया है, मैं इसे चरण-दर-चरण विकसित करूंगा। लेकिन चूंकि हमने उप-प्रश्नों को बड़े भावों में उपयोग करने से पहले उन्हें डिबग कर दिया है, इसलिए हम उत्तर के बारे में आश्वस्त हो सकते हैं।

खंड के साथ

ध्यान दें कि मानक SQL एक खंड के साथ प्रदान करता है जो एक उप-क्वेरी का नामकरण करते हुए एक SELECT कथन को उपसर्ग करता है। (इसका उपयोग पुनरावर्ती प्रश्नों के लिए भी किया जा सकता है, लेकिन हमें यहां इसकी आवश्यकता नहीं है।)

WITH RatingList AS
     (SELECT p.PersonID, t.Rating, COUNT(*) AS RatingCount
        FROM PersonTable AS p
        JOIN TransactionTable AS t
          ON p.TransactionID = t.TransactionID
       GROUP BY p.PersonID, t.Rating
     )
SELECT s.PersonID, s.Rating
  FROM RatingList AS s
  JOIN (SELECT s.PersonID, MAX(s.RatingCount) AS MaxRatingCount
          FROM RatingList AS s
         GROUP BY s.PersonID
       ) AS m
    ON s.PersonID = m.PersonID AND s.RatingCount = m.MaxRatingCount

यह लिखना आसान है। दुर्भाग्य से, MySQL अभी तक WITH क्लॉज का समर्थन नहीं करता है।

उपरोक्त SQL का अब Mac OS X 10.7.4 पर चलने वाले IBM Informix Dynamic Server 11.70.FC2 के विरुद्ध परीक्षण किया गया है। उस परीक्षण ने प्रारंभिक टिप्पणी में निदान की गई समस्या को उजागर किया। मुख्य उत्तर के लिए SQL बिना बदले सही ढंग से काम करता है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql में कई पंक्तियों को सम्मिलित करना

  2. MySQL मैच दो वर्णों के साथ काम नहीं करता है?

  3. पंक्तियों को कॉलम में गतिशील रूप से परिवर्तित करने के लिए MySQL क्वेरी

  4. पीडीओ अपवादों को कैसे संभालें

  5. डेटाबेस डिज़ाइन:एकाधिक टेबल बनाम एक टेबल