레일 : 열에서 고유 한 값을 선택하십시오.


238

이미 작동하는 솔루션이 있지만 왜 이것이 작동하지 않는지 알고 싶습니다.

ratings = Model.select(:rating).uniq
ratings.each { |r| puts r.rating }

고유 값을 선택하지만 인쇄하지는 않지만 중복을 포함하여 모든 값을 인쇄합니다. 그리고 그것은 문서에 있습니다 : http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields


답변:


449
Model.select(:rating)

이것의 결과는 Model객체 의 모음입니다 . 평범하지 않은 등급. 그리고 uniq관점에서 보면 완전히 다릅니다. 이것을 사용할 수 있습니다 :

Model.select(:rating).map(&:rating).uniq

또는 이것 (가장 효율적)

Model.uniq.pluck(:rating)

# rails 5+
Model.distinct.pluck(:rating)

최신 정보

레일즈 5.0.0.1부터는 위와 같이 "최상위"쿼리에서만 작동합니다. 콜렉션 프록시 (예 : "has_many"관계)에서는 작동하지 않습니다.

Address.distinct.pluck(:city) # => ['Moscow']
user.addresses.distinct.pluck(:city) # => ['Moscow', 'Moscow', 'Moscow']

이 경우 쿼리 후 중복 제거

user.addresses.pluck(:city).uniq # => ['Moscow']

나는 : group (: rating) .collect {| r | r.rating} map == collect이므로 사용한이 sintax에 대해 어디에서 읽을 수 있습니까 (& : rating)? Ruby의 설명서에서 이것을 보지 못했습니다.
alexandrecosta

@ user1261084 : .map (& : rating)을 이해 하려면 Symbol # to_proc 를 참조하십시오 . PragDave는 다음과 같이 설명합니다
dbenhur

63
이것이 Model.uniq.pluck(:rating)가장 효율적인 방법 이라는 점 은 주목할 가치가 있습니다. 이것은 배열에 SELECT DISTINCT적용 하는 대신 사용 하는 SQL을 생성 .uniq합니다.
Mikey

23
Rails 5에서는 다음과 같이 Model.uniq.pluck(:rating)될 것입니다.Model.distinct.pluck(:rating)
neurodynamic

2
has_many 관계에서 고유 한 값을 선택하려면 언제든지 할 수 있습니다Model.related_records.group(:some_column).pluck(:some_column)
Krzysztof Karski

92

을 사용 하려는 경우 고유 값만 반환 Model.select하므로을 사용할 수도 있습니다 DISTINCT. 이것은 적은 수의 행을 반환하고 많은 수의 행을 반환 한 다음 Rails에게 고유 한 값을 선택하도록 지시하는 것보다 약간 더 빠르다는 것을 의미하기 때문에 더 좋습니다.

Model.select('DISTINCT rating')

물론 이것은 데이터베이스가 DISTINCT키워드를 이해하고 제공 해야하는 경우에 제공됩니다.


6
Model.select("DISTINCT rating").map(&:rating)그냥 등급의 배열을 얻을 수 있습니다.
Kris

Rails 2.3을 사용하는 레거시 앱 사용자에게 적합
Mikey

3
예. 이것은 환상적으로 작동하지만 DISTINCT 속성 만 반환합니다. 고유 한 경우 전체 Model 객체를 어떻게 반환 할 수 있습니까? 따라서 속성이 고유 한 인스턴스에서 모델의 모든 속성에 액세스 할 수 있습니다.
zero_cool

@Jackson_Sandland Model 객체를 원한다면 테이블의 레코드에서 인스턴스화해야합니다. 그러나 레코드를 고유 한 값으로 선택하지는 않습니다 (여러 레코드 일 수 있음).
베니 시모

69

이것도 작동합니다.

Model.pluck("DISTINCT rating")

나는 pluck이 Ruby 1.9.x 이상이라고 생각합니다. 이전 버전을 사용하는 사람에게는 없습니다. 1.9x 이상인 경우, 루비 문서는 이것이 작동한다고 말합니다. Model.uniq.pluck (: rating)
kakubei

6
pluck이다 루비에 대한 종속성이없는 순수한 레일> 3.2 방법은 참조 1.9.x apidock.com/rails/v3.2.1/ActiveRecord/Calculations/pluck
다니엘 Rikowski을

34

추가 필드를 선택하려면 다음을 수행하십시오.

Model.select('DISTINCT ON (models.ratings) models.ratings, models.id').map { |m| [m.id, m.ratings] }

1
select extra fields<3 <3
cappie013

27
Model.uniq.pluck(:rating)

# SELECT DISTINCT "models"."rating" FROM "models"

이것은 SQL 문자열을 사용하지 않고 모델을 인스턴스화하지 않는 이점이 있습니다


3
Rails 5.1 / AR 5.1 => undefined method`uniq '에서 에러가 발생합니다.
Graham Slick

24
Model.select(:rating).uniq

이 코드는 레일 3.2 이후 'DISTINCT'(Array # uniq가 아님)로 작동합니다.


5
Model.select(:rating).distinct

2
이것은 공식적으로 유일하게 매우 효율적인 정답입니다. 그러나 .pluck(:rating)마지막에 추가 하면 OP가 요청한 것과 정확하게 일치합니다.
Sheharyar

5

내가 옳은 길을 가고 있다면 :

현재 검색어

Model.select(:rating)

객체 배열을 반환하고 쿼리를 작성했습니다.

Model.select(:rating).uniq

uniq는 객체 배열에 적용되며 각 객체에는 고유 한 ID가 있습니다. 배열의 각 객체가 uniq이므로 uniq이 작업을 올바르게 수행하고 있습니다.

별개의 등급을 선택하는 방법은 여러 가지가 있습니다.

Model.select('distinct rating').map(&:rating)

또는

Model.select('distinct rating').collect(&:rating)

또는

Model.select(:rating).map(&:rating).uniq

또는

Model.select(:name).collect(&:rating).uniq

하나 더, 첫 번째와 두 번째 쿼리 : SQL 쿼리로 고유 한 데이터를 찾습니다.

이러한 쿼리는 "london"과 "london"으로 간주되며 공간을 무시한다는 의미이므로 쿼리 결과에서 'london'을 한 번 선택합니다.

세 번째 및 네 번째 쿼리 :

SQL 쿼리로 데이터를 찾고 고유 한 데이터를 적용하려면 ruby ​​uniq mehtod를 적용하십시오. 이러한 쿼리는 "london"과 "london"이 다른 것으로 간주되므로 쿼리 결과에서 'london'과 'london'을 모두 선택합니다.

자세한 내용은 첨부 된 이미지를 참조하고 "Toured / Awaiting RFP"를 참조하십시오.

여기에 이미지 설명을 입력하십시오


6
map& collect는 동일한 방법에 대한 별명이므로 둘 다에 대한 예를 제공 할 필요는 없습니다.
Adam Lassek

4

일부 답변은 OP가 배열을 원한다는 점을 고려하지 않습니다.

모델에 수천 개의 레코드가있는 경우 다른 답변이 제대로 작동하지 않습니다

좋은 대답은 다음과 같습니다.

    Model.uniq.select(:ratings).map(&:ratings)
    => "SELECT DISTINCT ratings FROM `models` " 

먼저, 선택으로 인해 크기가 줄어든 모델 배열을 생성 한 다음 선택한 모델에있는 유일한 속성 (등급)을 추출하기 때문에


3

Mongoid와 같은 것을 찾는 사람이라면

Model.distinct(:rating)

이것은 지금 작동하지 않으며 이제 배수를 반환합니다.
EUPHORAY

별개의 반환하지 않습니다
dowi

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