2012-11-02 38 views
9

का उपयोग कर शीर्ष एन मान अपडेट करें मैं तालिका में कॉलम के शीर्ष 10 मानों को अपडेट करना चाहता हूं। मेरे पास तीन कॉलम हैं; id, account और accountrank। शीर्ष 10 मान प्राप्त करने के लिए मैं निम्नलिखित का उपयोग कर सकते हैं:पोस्टग्रेएसक्यूएल

SELECT * FROM accountrecords  
ORDER BY account DESC 
LIMIT 10; 

मुझे क्या करना चाहते हैं 1 - 10 की एक श्रृंखला, account की भयावहता के आधार पर होना करने के लिए accountrank में मान सेट करने के लिए है। क्या PostgreSQL में ऐसा करना संभव है?

+2

यदि आपके poatgres संस्करण 8.4 या ऊपर है, तो आप विंडोिंग फ़ंक्शंस + रैंक() या row_number() का उपयोग कर सकते हैं। – wildplasser

उत्तर

22
UPDATE accountrecords a 
SET accountrank = sub.rn 
FROM (
    SELECT id, row_number() OVER (ORDER BY account DESC NULLS LAST) AS rn 
    FROM accountrecords  
    ORDER BY account DESC NULLS LAST 
    LIMIT 10 
    ) sub 
WHERE sub.id = a.id; 

एक तालिका में शामिल होने से आम तौर पर तेजी से सहसंबद्ध सबक्वेरी से है। यह भी छोटा है।

window function row_number() के साथ विशिष्ट संख्याओं की गारंटी है। rank() (या संभवतः dense_rank()) का उपयोग करें यदि आप समान संख्या साझा करने के लिए account के बराबर मान वाले पंक्तियां चाहते हैं।

केवल तभी, जब account में NULL मूल्यों हो सकता है, आप तरह अवरोही क्रम के लिए NULLS LAST संलग्न करने के लिए की जरूरत है, या NULL मूल्यों प्रकार पर शीर्ष:

तो समवर्ती लिखने नहीं हो सकता एक्सेस, उपरोक्त क्वेरी दौड़ की स्थिति के अधीन है। पर विचार करें:

हालांकि, यदि यह मामला, की पूरी अवधारणा था हार्ड-कोड शीर्ष दस एक संदिग्ध दृष्टिकोण के साथ शुरू करने के लिए किया जाएगा।

1

निश्चित रूप से, आप अपने चयन कथन का एक सबक्वायरी में उपयोग कर सकते हैं। रैंक-ऑर्डर उत्पन्न करना मामूली नहीं है, लेकिन इसे करने के लिए कम से कम एक तरीका है। मैं इस परीक्षण किया है नहीं है, लेकिन मेरे सिर के ऊपर से:

update accountrecords 
set accountrank = 
    (select count(*) + 1 from accountrecords r where r.account > account) 
where id in (select id from accountrecords order by account desc limit 10); 

यह मोड़ है कि यदि दो रिकॉर्ड account के लिए एक ही मूल्य है, तो वे एक ही रैंक मिल जाएगा है। आप विचार कर सकते हैं एक विशेषता यह है कि ... :-)