एक व्युत्पन्न तालिका
में (FROM
. के अंदर सबक्वेरी क्लॉज), हम अपने डेटा को इस तरह से ऑर्डर करते हैं कि सभी पंक्तियाँ समान हों user_id
मान एक साथ आते हैं, game_detail
. के आधार पर उनके बीच आगे छँटाई के साथ अवरोही क्रम में।
अब, हम इस परिणाम-सेट का उपयोग करते हैं और सशर्त CASE..WHEN
. का उपयोग करते हैं पंक्ति क्रमांकन का मूल्यांकन करने के लिए भाव। यह एक लूपिंग तकनीक की तरह होगा (जिसका उपयोग हम एप्लिकेशन कोड में करते हैं, जैसे:PHP)। हम पिछली पंक्ति मानों को उपयोगकर्ता-परिभाषित चर में संग्रहीत करेंगे, और फिर पिछली पंक्ति के विरुद्ध वर्तमान पंक्ति के मान (मानों) की जांच करेंगे। अंत में, हम तदनुसार पंक्ति संख्या निर्दिष्ट करेंगे।
संपादित करें: MySQL पर आधारित docs और @Gordon Linoff का अवलोकन:
<ब्लॉकक्वॉट>उपयोगकर्ता चर वाले भावों के मूल्यांकन का क्रम अपरिभाषित है। उदाहरण के लिए, इस बात की कोई गारंटी नहीं है कि SELECT @a, @a:[email protected]ए> +1 पहले @a का मूल्यांकन करता है और फिर असाइनमेंट करता है।
हमें पंक्ति संख्या का मूल्यांकन करने और user_id
. असाइन करने की आवश्यकता होगी @u
. का मान एक ही व्यंजक के भीतर चर।
SET @r := 0, @u := 0;
SELECT
@r := CASE WHEN @u = dt.user_id
THEN @r + 1
WHEN @u := dt.user_id /* Notice := instead of = */
THEN 1
END AS user_game_rank,
dt.user_id,
dt.game_detail,
dt.game_id
FROM
( SELECT user_id, game_id, game_detail
FROM game_logs
ORDER BY user_id, game_detail DESC
) AS dt
परिणाम
| user_game_rank | user_id | game_detail | game_id |
| -------------- | ------- | ----------- | ------- |
| 1 | 6 | 260 | 11 |
| 2 | 6 | 100 | 10 |
| 1 | 7 | 1200 | 10 |
| 2 | 7 | 500 | 11 |
| 3 | 7 | 260 | 12 |
| 4 | 7 | 50 | 13 |
MySQL से एक दिलचस्प नोट Docs , जिसे मैंने हाल ही में खोजा:
<ब्लॉकक्वॉट>MySQL की पिछली रिलीज़ ने SET के अलावा अन्य स्टेटमेंट्स में auser वेरिएबल को मान असाइन करना संभव बना दिया। यह कार्यक्षमता पश्चगामी संगतता के लिए MySQL 8.0 में समर्थित है, लेकिन MySQL के भावी रिलीज़ में इसे हटाया जा सकता है।
इसके अलावा, एक साथी SO सदस्य के लिए धन्यवाद, MySQL टीम द्वारा इस ब्लॉग पर आया:https://mysqlserverteam.com/row-numbering-ranking-how-to-use-less-user-variables-in-mysql-queries/
सामान्य अवलोकन यह है कि ORDER BY
. का उपयोग करना एक ही क्वेरी ब्लॉक में उपयोगकर्ता चर के मूल्यांकन के साथ, यह सुनिश्चित नहीं करता है कि मान हमेशा सही होंगे। जैसे, MySQL अनुकूलक हो सकता है जगह पर आएं और हमारे अनुमानित . को बदलें मूल्यांकन का क्रम।
इस समस्या का सबसे अच्छा तरीका यह होगा कि आप MySQL 8+ में अपग्रेड करें और Row_Number()
कार्यक्षमता:
स्कीमा (MySQL v8.0)
SELECT user_id,
game_id,
game_detail,
ROW_NUMBER() OVER (PARTITION BY user_id
ORDER BY game_detail DESC) AS user_game_rank
FROM game_logs
ORDER BY user_id, user_game_rank;
परिणाम
| user_id | game_id | game_detail | user_game_rank |
| ------- | ------- | ----------- | -------------- |
| 6 | 11 | 260 | 1 |
| 6 | 10 | 100 | 2 |
| 7 | 10 | 1200 | 1 |
| 7 | 11 | 500 | 2 |
| 7 | 12 | 260 | 3 |
| 7 | 13 | 50 | 4 |