2010-07-07 6 views
9

मैं एक प्रश्न के चारों ओर अपना सिर पाने की कोशिश कर रहा हूं और मैं इसे समझ नहीं पा रहा हूं। अगर कोई मुझे पॉइंटर देता है तो मैं सराहना करता हूं। मैं क्या हासिल करने की कोशिश कर रहा हूँ का एक सरल उदाहरण के रूप में, मैं डेटाबेसरैंकिंग पदों को स्टोर करने के लिए MySQL अद्यतन कथन

Score|Ranking 
------------- 
100 |0 
200 |0 
300 |0 

में इन रिकॉर्ड है और मैं रैंकिंग क्षेत्र जो इतना उच्चतम स्कोर मिला है के आधार पर 1,2,3 शामिल करना चाहते हैं परिणाम होना चाहिए:

Score|Ranking 
------------- 
100 |3 
200 |2 
300 |1 

पल में, मैं इन सभी रिकॉर्ड के लिए अगले पाश के लिए एक कर रहा हूँ, लेकिन यह देखते हुए वास्तव में है कि कुछ हजार हो सकता है कि - कि हमेशा के लिए ले सकता है! क्या किसी के पास जादू की क्वेरी पर कोई विचार है जो इसे एक ही समय में करेगा?

उत्तर

4

MySQL में, आप पंक्ति_number का उपयोग कर सकते हैं।

एक SELECT में इसका उपयोग करने की Here's an example:

select @rownum:[email protected]+1 ‘rank’, p.* 
from player p, (SELECT @rownum:=0) r 
order by score desc; 

आप INSERT INTO एक SELECT इस तरह का उपयोग कर रहे हैं, तो आप अपनी रैंकिंग मिल जाएगा।

+0

+1: आम तौर पर मैं कहूंगा कि यह एक दृश्य में होना चाहिए, लेकिन MySQL दृश्य परिवर्तनीय उपयोग की अनुमति नहीं देते हैं। रैंकिंग मान प्राप्त करने के लिए उप-चयन में COUNT का उपयोग करने का एक विकल्प है जो मुझे लगता है कि एक दृश्य में काम करेगा ... –

+10

यह डीबी में मानों को अपडेट करता है? – quantumSoup

4

यह एक इनलाइन अपडेट स्टेटमेंट बनाता है जो आपके खिलाड़ियों को परिवर्तनीय @rc द्वारा बढ़ाएगा। मैंने इसे कई मामलों में कई बार इस्तेमाल किया है, यह अच्छी तरह से काम करता है और इसे डीबी पक्ष पर रखता है।

SET @rc = 0; 
UPDATE players JOIN (SELECT @rc := @rc + 1 AS rank, id FROM players ORDER BY rank DESC) 
AS order USING(id) SET players.rank = order.rank; 

id अपने players तालिका के लिए प्राथमिक कुंजी माना जाता है।

SET @r=0; 
UPDATE table SET Ranking= @r:= (@r+1) ORDER BY Score DESC; 

/* use this if you just want to pull it from the db, but don't update anything */ 
SET @r=0; 
SELECT *, @r:= (@r+1) as Ranking FROM table ORDER BY Score DESC; 
16

यहाँ यह करने के लिए एक तरीका है:

set @currentRank = 0, 
    @lastRating = null, 
    @rowNumber = 1; 
update 
    `table` r 
    inner join (
     select 
      `primaryID`, 
      @currentRank := if(@lastRating = `score`, @currentRank, @rowNumber) `rank`, 
      @rowNumber := @rowNumber + if(@lastRating = `score`, 0, 1) `rowNumber`, 
      @lastRating := `score` 
     from `table` 
     order by `score` desc 
    ) var on 
     var.`primaryID` = r.`primaryID` 
set 
    r.`rank` = var.`rank` 

i यह परीक्षण करने के अलावा इस पर कोई प्रदर्शन जांच नहीं करता है कि यह

+1

डीओके संस्करण देखें - इसे एसईटी कथन की आवश्यकता नहीं है, यह पूरी तरह से निहित है। –

+2

इस अर्थ में स्वयं निहित है कि यह एक ही प्रश्न में है, हां; लेकिन ऐसा इसलिए है क्योंकि वह SELECT subquery में @rownum सेट कर रहा है। जो मुझे लगता है कि गड़बड़ लग रहा है। – quantumSoup

+0

सौंदर्य दर्शक की नजर में है, लेकिन एक कथन प्रस्तुत करने की क्षमता में समस्या होने की संभावना कम है –

0

[अंतराल एसक्यूएल अद्यतन कार्यों के लिए]

चयन मैं आप इसे करने का मेरा तरीका दिखा रहा हूँ:

set @currentRank = 0, 
    @lastRating = null, 
    @rowNumber = 1; 
select 
    *, 
    @currentRank := if(@lastRating = `score`, @currentRank, @rowNumber) `rank`, 
    @rowNumber := @rowNumber + if(@lastRating = `score`, 0, 1) `rowNumber`, 
    @lastRating := `score` 
from `table` 
order by `score` desc 

अद्यतन

2
SET @r = 0; 
UPDATE players JOIN (SELECT @r := @r + 1 AS rank, id FROM players ORDER BY rank DESC) 
AS sorted USING(id) SET players.rank = sorted.rank;