activerecord로 마지막 N 레코드를 얻는 방법은 무엇입니까?


163

함께 :limit쿼리에, 내가 먼저 N 기록을 얻을 것이다. 마지막 N 레코드를 얻는 가장 쉬운 방법은 무엇입니까?

답변:


143

이와 같은 활성 레코드 쿼리는 원하는 것을 얻을 것이라고 생각합니다 ( 'Something'은 모델 이름입니다).

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

데이터를 두 번 주문할 필요가없는 것 같습니다. 현재 카운트를 먼저 가져 와서 오프셋으로 사용하고 있습니다.
JtR

그것은 내가 생각한 다른 방법 이었지만 1 대신 데이터베이스에 대한 2 개의 쿼리 이후 더 많은 작업처럼 보입니다. 루프 정렬을 허용 할 수 있다고 가정합니다. 당시에. (즉, records.reverse.each do ..)
Dan McNevin

또는, 배열을 뒤집지
Dan

1
Rails 3의 경우 대신 Bongs의 답변을 참조하십시오. 이 방법은 여전히 ​​작동하지만 더 이상 선호되는 방법은 아닙니다.
Kyle Heironimus

3
#find (: all) 호출은 더 이상 사용되지 않습니다. 대신 #all을 직접 호출하십시오.
Snowcrash

262

이것이 Rails 3 Way입니다

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

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

4
Postgres와 함께 사용해보십시오! 나는 분명히 처음에 문제가 있었다. SQL에서는 순서를 지정하지 않으면 순서가 보장되지 않지만 MySQL은 더 관대합니다.
Ghoti

5
참고 :이 방법은 성능 측면에서 레일스 3.1 이상이 아닙니다. SomeModel.last (5)는 select 문을 제한없이 실행하여 SomeModel의 모든 레코드를 배열로 Ruby에 반환 한 후 Ruby는 마지막 요소 (5)를 선택합니다. 효율성 측면에서 현재, 특히 잠재적으로 많은 요소가있는 경우 제한을 사용하려고합니다.
DRobinson

14
정확히해야 할 SELECT "items".* FROM "items" ORDER BY id DESC LIMIT 50
firedev

7
Rails 4에서 .last ()에 의해 생성 된 쿼리는 Nick이 언급 한 것처럼 최적입니다
Jimmie Tyrrell

1
SomeModel.last(5).class== 이므로 Rails 4+에서는 올바르지 않습니다 Array. 올바른 접근 방식은 SomeModel.limit(5).order('id desc')Arthur Neves에 따른 것입니다.SELECT \"somemodels\".* FROM \"somemodels\" ORDER BY id desc LIMIT 5
Amin Ariana

50

레일스 3.1에서하는 새로운 방법은 SomeModel.limit(5).order('id desc')


14
last(5)추가 체인에 대한 범위를 반환하기 때문에이 방법 이 더 좋습니다 .
lulalala

3
내가 사용 SomeModel.limit(100).reverse_order레일 4 (에 guides.rubyonrails.org/... 그것은 동일합니다).
Ivan Black

@lulalala 언급 "더 체인에 대한 범위"의 예 : 하나의 컬럼 만 필요하면 SomeModel.limit(5).order('id desc').pluck(:col)할 것입니다 SELECT SomeModel.col FROM SomeModel ORDER BY id desc LIMIT 5훨씬 더 효율적 모든 열을 잡아 하나를 제외한 모든 열이 폐기보다 어떤 SomeModel.last(5).map(&:col) 않는 SELECT *대신에 SELECT col(당신이 호출 할 수 없습니다 뽑은 후 마지막; 게으른 평가 사슬은 마지막으로 끝납니다).
Kanat Bolazar

33

Rails 5 (및 Rails 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
실제로 Rails 3도 마찬가지입니다. ;)
Joshua Pinter

32

들어 레일 4 버전 이상 :

가장 오래된 항목 을 원하면 다음과 같이 해보십시오

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

당신이 마지막으로 최신 항목 을 원한다면 이런 식으로 시도 할 수 있습니다 ..

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

1
이것은 Rails 4에 대한 최신 답변으로 허용되는 것보다 더 보입니다. 가장 최근 구문은 다음과 같아야한다고 생각합니다.YourModel.all.order(id: :desc).limit(5)
jmarceli

@ user2041318 :이 새로운 구문에 대한 감사없이" "
가갠 가미

2
Order ()는 모든 레코드를 반환합니다. 체인 필요가 없습니다 YourModel.all.order()으로 동일하기 때문에YourModel.order()
시스코 퀸 테로

26

해결책은 다음과 같습니다.

SomeModel.last(5).reverse

레일이 게으 르기 때문에 결국 "SELECT table. * FROM table ORDER BY table. idDESC LIMIT 5" 와 같은 SQL로 데이터베이스에 충돌합니다 .


이것은SomeModel
John Hinnegan

더 나은 접근 방식은 limit (); 이것은 효율적이지 않습니다.
Anurag

3
@Developer는 절대적으로 옳습니다. 실행 된 SQL은 SELECT table .* FROM table` ORDER BY table입니다. idDESC 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

작동합니다.


3

우리는 레일을 사용 Model.last(5)하거나 사용할 수 있습니다 Model.limit(5).order(id: :desc)5.2


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 코드를 사용하면서 ID를 배열로 신속하게 제공합니다.


Challenge.limit(5).order('id desc').ids잘 작동합니다 :)
Koen.

0

Rails 3에서 오름차순을 지정하는 모델에 기본 범위가있는 경우 위의 Arthur Neves가 지정한 순서 대신 순서를 다시 사용해야합니다.

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

키는 하위 선택입니다. 먼저 원하는 마지막 메시지를 정의한 다음 오름차순으로 정렬해야합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.