एक्टिवरकॉर्ड के साथ अंतिम एन रिकॉर्ड कैसे प्राप्त करें?


163

साथ :limitक्वेरी में, मैं पहले एन रिकॉर्ड मिल जाएगा। अंतिम एन रिकॉर्ड प्राप्त करने का सबसे आसान तरीका क्या है?

जवाबों:


143

इस तरह से एक सक्रिय रिकॉर्ड क्वेरी मुझे लगता है कि आपको वह मिलेगा जो आप चाहते हैं ('कुछ' मॉडल का नाम है):

Something.find(:all, :order => "id desc", :limit => 5).reverse

संपादित करें : जैसा कि टिप्पणियों में बताया गया है, एक और तरीका:

result = Something.find(:all, :order => "id desc", :limit => 5)

while !result.empty?
        puts result.pop
end

डेटा को दो बार ऑर्डर करने के लिए अनावश्यक लगता है, मैं वर्तमान में पहली गिनती प्राप्त कर रहा हूं और ऑफसेट के साथ इसका उपयोग कर रहा हूं
जेटीआर

यह वह दूसरी विधि थी जिसके बारे में मैं सोच रहा था, लेकिन ऐसा लगता है कि डेटाबेस के विरूद्ध 2 प्रश्न हैं क्योंकि 1 के बजाय 1। मुझे लगता है कि आपको किसी बिंदु पर सरणी पर पुनरावृति करने की आवश्यकता है, इसलिए आप माणिक प्रकार दे सकते हैं। यह उस समय था। (यानी।
record.reverse.each

वैकल्पिक रूप से, आप सरणी रिवर्स नहीं कर सकता है और बल्कि यह पीछे .. से सरणी पर पुनरावृति करने Array.pop का उपयोग ruby-doc.org/core-1.8.7/classes/Array.html#M000280
दान McNevin

1
रेल 3 के लिए, बोंग्स का उत्तर बदले में देखें। यह तरीका अभी भी काम करता है, लेकिन अब पसंदीदा तरीका नहीं है।
काइल हिरोनिमस

3
#Find (: सभी) को कॉल करना पदावनत है। इसके बजाय सीधे # कॉल करें।
स्नोक्रैश

262

यह 3 तरह से रेल है

SomeModel.last(5) # last 5 records in ascending order

SomeModel.last(5).reverse # last 5 records in descending order

4
Postgres के साथ यह कोशिश करो! मुझे निश्चित रूप से पहले से परेशानी थी। जब तक आप इसे निर्दिष्ट नहीं करते हैं तब तक SQL में आदेश की गारंटी नहीं होती है, लेकिन MySQL अधिक क्षमाशील है।
घोटी

5
नोट: यह इसे लागू करने का एक अच्छा तरीका नहीं है, प्रदर्शन-वार - कम से कम रेल 3.1 तक नहीं। SomeModel.last (5) एक सीमा के बिना Select स्टेटमेंट को निष्पादित करेगा, SomeModel के सभी रिकॉर्ड को Ruby को एक अरै के रूप में लौटाएगा, जिसके बाद रूबी अंतिम (5) तत्वों को निकालेगा। दक्षता-बुद्धिमान, वर्तमान में, आप सीमा का उपयोग करना चाहते हैं - खासकर यदि आपके पास संभावित रूप से कई तत्व हैं।
डॉबिन्सन जूल

14
यह ठीक वही करता है जो इसे करना चाहिए:SELECT "items".* FROM "items" ORDER BY id DESC LIMIT 50
निकाल दिया

7
रेल में 4 .last द्वारा उत्पन्न क्वेरी () निक के रूप में भी इष्टतम है
जिम्मी टाइरेल

1
यह SomeModel.last(5).class== के बाद से रेल 4+ के लिए गलत है Array। सही दृष्टिकोण SomeModel.limit(5).order('id desc')आर्थर नेव्स के अनुसार है, जिसके परिणामस्वरूपSELECT \"somemodels\".* FROM \"somemodels\" ORDER BY id desc LIMIT 5
अमीन एरियाना

50

नए तरीके से इसे करने के लिए रेल 3.1 है SomeModel.limit(5).order('id desc')


14
यह उससे बेहतर है last(5)क्योंकि यह आगे के लिए एक गुंजाइश देता है।
लूलालाल

3
मैं SomeModel.limit(100).reverse_orderरेल्स 4 पर प्रयोग करता हूं ( guide.rubyonrails.org/… ) यह वही है।
इवान ब्लैक

@ लल्लूलाल द्वारा उल्लिखित "आगे की मंज़िल के लिए गुंजाइश" का उदाहरण: यदि आपको केवल एक कॉलम की आवश्यकता है, SomeModel.limit(5).order('id desc').pluck(:col)तो ऐसा करेंगे SELECT SomeModel.col FROM SomeModel ORDER BY id desc LIMIT 5जो सभी कॉलमों को हथियाने और सभी स्तंभों को छोड़ने की तुलना में बहुत अधिक कुशल है, लेकिन इसके बजाय एक कॉलम SomeModel.last(5).map(&:col) जिसके साथ आप कॉल करने के बाद प्लक नहीं कर सकते हैं अंतिम; आलसी-eval श्रृंखला अंतिम के साथ समाप्त होती है)। SELECT *SELECT col
कनात बोलाज़ार

33

रेल 5 के लिए (और संभावित रेल 4)

खराब:

Something.last(5)

इसलिये:

Something.last(5).class
=> Array

इसलिए:

Something.last(50000).count

संभावना है कि आपकी स्मृति को उड़ा देगा या हमेशा के लिए ले जाएगा।

अच्छी एप्रोच:

Something.limit(5).order('id desc')

इसलिये:

Something.limit(5).order('id desc').class
=> Image::ActiveRecord_Relation

Something.limit(5).order('id desc').to_sql
=> "SELECT  \"somethings\".* FROM \"somethings\" ORDER BY id desc LIMIT 5"

उत्तरार्द्ध एक अज्ञात गुंजाइश है। आप इसे चेन कर सकते हैं, या इसे ऐरे से बदल सकते हैं .to_a। इसलिए:

Something.limit(50000).order('id desc').count

... एक सेकंड लगता है।


1
और यहां तक ​​कि रेल 3, वास्तव में। ;)
जोशुआ पिंटर

32

के लिए रेल 4 और संस्करण से ऊपर:

आप कुछ इस तरह की कोशिश कर सकते हैं यदि आप पहली सबसे पुरानी प्रविष्टि चाहते हैं

YourModel.order(id: :asc).limit(5).each do |d|

आप कुछ इस तरह की कोशिश कर सकते हैं यदि आप अंतिम नवीनतम प्रविष्टियां चाहते हैं

YourModel.order(id: :desc).limit(5).each do |d|

1
ऐसा लगता है कि स्वीकृत 4 की तुलना में रेल 4 के उत्तर की तारीख तक अधिक है। मुझे लगता है कि सबसे हालिया वाक्यविन्यास इस तरह दिखना चाहिए:YourModel.all.order(id: :desc).limit(5)
jmarceli

@ user2041318: इस नए वाक्यविन्यास के लिए धन्यवाद" "
गगन गामी

2
आदेश () सभी रिकॉर्ड लौटाता है। श्रृंखला की कोई आवश्यकता नहीं है YourModel.all.order()क्योंकि यह उसी प्रकार हैYourModel.order()
फ्रांसिस्को क्विन्टो

26

समाधान यहाँ है:

SomeModel.last(5).reverse

चूंकि रेल आलसी है, इसलिए यह अंततः एसक्यूएल के साथ डेटाबेस को हिट करेगा जैसे: "का चयन करें table। * ओर से । table द्वारा जारी करें tableidDESC LIMIT 5"।


यह सभी रिकॉर्डSomeModel
जॉन हेनेगन

सीमा तक बेहतर दृष्टिकोण होगा (); यह कुशल नहीं दिखता है।
अनुराग

3
@ डायवर्टर बिल्कुल सही है। SQL निष्पादित किया गया था: SELECT तालिका तालिका .* FROM `आदेश द्वारा tableidDESC LIMIT में 5` यह है नहीं एक सभी का चयन प्रदर्शन
ddavison

4

यदि आपको परिणामों पर कुछ आदेश देने की आवश्यकता है तो उपयोग करें:

Model.order('name desc').limit(n) # n= number

यदि आपको किसी ऑर्डर देने की आवश्यकता नहीं है, और केवल तालिका में सहेजे गए रिकॉर्ड की आवश्यकता है तो उपयोग करें:

Model.last(n) # n= any number

4

मेरी रेल (rails 4.2)परियोजना में, मैं उपयोग करता हूं

Model.last(10) # get the last 10 record order by id

और यह काम करता है।



2

कोशिश करो:

Model.order("field_for_sort desc").limit(5)

2
आपको यह बताना चाहिए कि यह समाधान व्यवहार्य क्यों है।
Phiter

1

मुझे लगता है कि "प्लक" विधि का उपयोग करने के लिए यह क्वेरी बेहतर / तेज़ है, जो मुझे पसंद है:

Challenge.limit(5).order('id desc')

यह आउटपुट के रूप में एक ActiveRecord देता है; तो आप इस तरह से .pluck का उपयोग कर सकते हैं:

Challenge.limit(5).order('id desc').pluck(:id)

जो इष्टतम SQL कोड का उपयोग करते हुए जल्दी से आईडी को एक सरणी के रूप में देता है।


Challenge.limit(5).order('id desc').idsके रूप में अच्छी तरह से काम करेंगे :)
Koen।

0

यदि आपके पास अपने मॉडल में एक डिफ़ॉल्ट स्कोप है जो रेल 3 में आरोही क्रम को निर्दिष्ट करता है, तो आपको ऊपर दिए गए आर्थर नेव्स द्वारा निर्दिष्ट आदेश के बजाय रीऑर्डर का उपयोग करने की आवश्यकता होगी:

Something.limit(5).reorder('id desc')

या

Something.reorder('id desc').limit(5)

0

मान लें कि N = 5 और आपका मॉडल है Message, आप कुछ इस तरह से कर सकते हैं:

Message.order(id: :asc).from(Message.all.order(id: :desc).limit(5), :messages)

Sql को देखें:

SELECT "messages".* FROM (
  SELECT  "messages".* FROM "messages"  ORDER BY "messages"."created_at" DESC LIMIT 5
) messages  ORDER BY "messages"."created_at" ASC

कुंजी उपशम है। पहले हमें यह परिभाषित करने की आवश्यकता है कि हम कौन से अंतिम संदेश चाहते हैं और फिर हमें उन्हें आरोही क्रम में लाना होगा।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.