MySQL के साथ, मैं एक तालिका में रिकॉर्ड इंडेक्स वाले कॉलम को कैसे उत्पन्न कर सकता हूं?


100

क्या किसी भी तरह से मैं एक क्वेरी से वास्तविक पंक्ति संख्या प्राप्त कर सकता हूं?

मैं स्कोर नामक फ़ील्ड द्वारा लीग_गर्ल नामक एक टेबल ऑर्डर करने में सक्षम होना चाहता हूं; और उपयोगकर्ता नाम और उस उपयोगकर्ता नाम की वास्तविक पंक्ति स्थिति लौटाएं।

मैं उपयोगकर्ताओं को रैंक करना चाहता हूं इसलिए मैं बता सकता हूं कि कोई विशेष उपयोगकर्ता कहां है, अर्थात। जो 200 में से 100 स्थान पर है, अर्थात

User Score Row
Joe  100    1
Bob  50     2
Bill 10     3

मैं यहाँ पर कुछ समाधान देखा है, लेकिन मैं उनमें से ज्यादातर की कोशिश की है और उनमें से कोई भी वास्तव में पंक्ति संख्या वापस नहीं है।

मैंने यह कोशिश की है:

SELECT position, username, score
FROM (SELECT @row := @row + 1 AS position, username, score 
       FROM league_girl GROUP BY username ORDER BY score DESC) 

जैसा व्युत्पन्न हुआ

... लेकिन यह पंक्ति की स्थिति को लौटाने के लिए प्रतीत नहीं होता है।

कोई विचार?


पंक्ति एक पंजीकृत नाम है या आप प्राथमिक कुंजी द्वारा ऑर्डर करना चाहते हैं?
सरफराज

SQL में, पंक्ति संख्या वास्तव में महत्वपूर्ण नहीं हैं। आपको क्या करना चाहिए, अपनी मेज पर एक ऑटो वेतन वृद्धि प्राथमिक कुंजी जोड़ें।
सिमेंडो

9
प्राथमिक कुंजी को एक पंक्ति पहचानकर्ता की आवश्यकता होनी चाहिए क्योंकि वे वास्तविक पंक्ति स्थिति के लिए विश्वसनीय नहीं हैं।
TheBounder

3
इसके अलावा, चूंकि पंक्ति संख्या स्कोर का एक फ़ंक्शन होगा, जो मुझे लगता है कि एक स्थिर मूल्य नहीं है, जिससे यह एक ऑटो वेतन वृद्धि मूल्य (प्राथमिक कुंजी या नहीं) इच्छित परिणाम नहीं देगा।
कासपर्जज

आप एक कस्टम फ़ंक्शन के लिए बदसूरत बचाना चाहते हैं, datamakessense.com/mysql-rownum-row-number-function
AdrianBR

जवाबों:


174

आप निम्नलिखित कोशिश करना चाहते हो सकता है:

SELECT  l.position, 
        l.username, 
        l.score,
        @curRow := @curRow + 1 AS row_number
FROM    league_girl l
JOIN    (SELECT @curRow := 0) r;

JOIN (SELECT @curRow := 0)भाग एक अलग आवश्यकता के बिना चर प्रारंभ की अनुमति देता है SETआदेश।

परीक्षण का मामला:

CREATE TABLE league_girl (position int, username varchar(10), score int);
INSERT INTO league_girl VALUES (1, 'a', 10);
INSERT INTO league_girl VALUES (2, 'b', 25);
INSERT INTO league_girl VALUES (3, 'c', 75);
INSERT INTO league_girl VALUES (4, 'd', 25);
INSERT INTO league_girl VALUES (5, 'e', 55);
INSERT INTO league_girl VALUES (6, 'f', 80);
INSERT INTO league_girl VALUES (7, 'g', 15);

टेस्ट क्वेरी:

SELECT  l.position, 
        l.username, 
        l.score,
        @curRow := @curRow + 1 AS row_number
FROM    league_girl l
JOIN    (SELECT @curRow := 0) r
WHERE   l.score > 50;

परिणाम:

+----------+----------+-------+------------+
| position | username | score | row_number |
+----------+----------+-------+------------+
|        3 | c        |    75 |          1 |
|        5 | e        |    55 |          2 |
|        6 | f        |    80 |          3 |
+----------+----------+-------+------------+
3 rows in set (0.00 sec)

19
आप बयान को कॉमा के साथ @curRowबदलकर भी शुरू कर सकते हैं JOIN, जैसे:FROM league_girl l, (SELECT @curRow := 0) r
माइक

2
@ माइक: यह सच है। और वह शायद खाने वाला भी है। इस टिप को शेयर करने के लिए धन्यवाद।
डैनियल वेसलो

2
@smhnaji MySQL के लिए आवश्यक है कि हर "व्युत्पन्न तालिका" को एक नाम दिया जाए। मैंने इसे "आर" कहने का फैसला किया :) ... इसका इस मामले में बहुत कम उद्देश्य है, लेकिन आप इसे सामान्य रूप से व्युत्पन्न तालिका के संदर्भ गुणों के लिए उपयोग करेंगे, जैसे कि यह एक वास्तविक तालिका थी।
डैनियल वेसलो

20
लोगों को इस बात की जानकारी होनी चाहिए कि किसी आदेश के होने से पहले इस पंक्ति संख्या की गणना की जाती है, इसलिए यदि क्रम पंक्ति क्रम को बदल देता है तो संख्याएँ उछल सकती हैं।
ग्रिम ...

7
क्या इस पंक्ति संख्या को पाने के बाद गणना करने का कोई तरीका है ORDER BY?
पियरे डे लेसिन 12


7

यहां मेरे द्वारा उपयोग किए गए टेम्पलेट की संरचना है:

  select
          /*this is a row number counter*/
          ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) 
          as rownumber,
          d3.*
  from 
  ( select d1.* from table_name d1 ) d3

और यहाँ मेरा काम कोड है:

select     
           ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) 
           as rownumber,
           d3.*
from
(   select     year( d1.date ), month( d1.date ), count( d1.id )
    from       maindatabase d1
    where      ( ( d1.date >= '2013-01-01' ) and ( d1.date <= '2014-12-31' ) )
    group by   YEAR( d1.date ), MONTH( d1.date ) ) d3

सही, आकर्षण और टेम्पलेट जैसे कार्यों को पैरामीटर के रूप में सबक्वेरी के साथ पुन: उपयोग किया जा सकता है ..
Zavael

यह समाधान भी काम करता है यदि आपकी आधार क्वेरी ग्रुप BY
डेव आर

4

आप भी उपयोग कर सकते हैं

SELECT @curRow := ifnull(@curRow,0) + 1 Row, ...

काउंटर वेरिएबल को इनिशियलाइज़ करने के लिए।


3
@curRowआपके पास वर्तमान सत्र में इस क्वेरी को चलाने के अंतिम समय से अभी भी मान हो सकता है।
बिल करविन

सही है, लेकिन केवल यदि आप एक ही कनेक्शन इंस्टेंस पर फिर से क्वेरी कर रहे हैं। कनेक्शन बंद होने के बाद स्थानीय चर स्वचालित रूप से निपट जाते हैं।
चूल्हा

हाँ, यही मेरा मतलब है जब मैंने कहा "वर्तमान सत्र में।"
बिल कार्विन

3

MySQL का मानना ​​है कि यह समर्थन करता है, आप आसानी से एक मानक SQL सबक्वेरी के साथ ऐसा कर सकते हैं:

select 
    (count(*) from league_girl l1 where l2.score > l1.score and l1.id <> l2.id) as position,
    username,
    score
from league_girl l2
order by score;

प्रदर्शित परिणामों की बड़ी मात्रा के लिए, यह थोड़ा धीमा होगा और आप इसके बजाय एक स्व-सम्मिलित में स्विच करना चाहेंगे।


3

यदि आप केवल फ़ील्ड स्कोर द्वारा आदेश के बाद एक विशिष्ट उपयोगकर्ता की स्थिति जानना चाहते हैं, तो आप बस अपनी तालिका से सभी पंक्ति का चयन कर सकते हैं जहां फ़ील्ड स्कोर वर्तमान उपयोगकर्ता स्कोर से अधिक है। और इस वर्तमान उपयोगकर्ता की स्थिति जानने के लिए पंक्ति संख्या + 1 का उपयोग करें।

यह मानते हुए कि आपकी तालिका है league_girlऔर आपका प्राथमिक क्षेत्र है id, आप इसका उपयोग कर सकते हैं:

SELECT count(id) + 1 as rank from league_girl where score > <your_user_score>

0

मुझे मूल उत्तर अविश्वसनीय रूप से मददगार लगा, लेकिन मैं उन पंक्तियों के एक निश्चित सेट को हथियाना चाहता था जो मैं सम्मिलित कर रहा था। जैसे, मैंने पूरे मूल उत्तर को एक उपशम में लपेट दिया ताकि मैं उस पंक्ति संख्या को संदर्भित कर सकूं जिसे मैं सम्मिलित कर रहा था।

SELECT * FROM 
( 
    SELECT *, @curRow := @curRow + 1 AS "row_number"
    FROM db.tableName, (SELECT @curRow := 0) r
) as temp
WHERE temp.row_number BETWEEN 1 and 10;

एक उपश्रेणी में एक उपकुंजी होना बहुत ही कुशल नहीं है, इसलिए यह परीक्षण के लायक होगा कि क्या आपको अपने SQL सर्वर को इस क्वेरी को संभालने से बेहतर परिणाम मिलता है, या पूरी तालिका को लाने और आवेदन / वेब सर्वर को इस तथ्य के बाद पंक्तियों में हेरफेर करने में मदद मिलती है ।

निजी तौर पर मेरा एसक्यूएल सर्वर अत्यधिक व्यस्त नहीं है, इसलिए इसे नेस्टेड उपश्रेणियों को संभालना बेहतर था।


0

मुझे पता है कि ओपी एक mysqlउत्तर के लिए पूछ रहा है, लेकिन जब से मैंने पाया कि अन्य उत्तर मेरे लिए काम नहीं कर रहे हैं,

  • उनमें से ज्यादातर के साथ विफल order by
  • या वे बस बहुत अक्षम हैं और एक मोटी तालिका के लिए आपकी क्वेरी को बहुत धीमा कर देते हैं

इसलिए मेरे जैसे अन्य लोगों के लिए समय बचाने के लिए, उन्हें डेटाबेस से पुनर्प्राप्त करने के बाद पंक्ति को अनुक्रमित करें

PHP में उदाहरण:

$users = UserRepository::loadAllUsersAndSortByScore();

foreach($users as $index=>&$user){
    $user['rank'] = $index+1;
}

उदाहरण के लिए PHP का उपयोग ऑफसेट और पेजिंग के लिए सीमा:

$limit = 20; //page size
$offset = 3; //page number

$users = UserRepository::loadAllUsersAndSortByScore();

foreach($users as $index=>&$user){
    $user['rank'] = $index+1+($limit*($offset-1));
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.