2017-09-14 4 views
0

を複製:のActiveRecord:フィルタリングこのテーブルを考えると

結果の関係が

  • すべての属性が
  • を埋めている必要があります場合、私は、ActiveRecordの(Railsの4.2、PostgreSQLの)を使用して、このテーブルを照会することができますどのように
    Users 
    | id | name | active | 
    | 1 | bob | true | 
    | 2 | bob | false | 
    | 3 | alice | false | 
    

  • 重複する名前が含まれていない
  • は、非アクティブなものに優先してアクティブなレコードを優先します。
  • カウントが整数
  • を返します.countを呼び出すことができるようActiveRecordのまま::関係

は正しい結果セットには、次のようになります。私はこれまで試した

Users 
| id | name | active | 
| 1 | bob | true | 
| 3 | alice | false | 

何:

# Works as for the result set, but raises when calling .count 
User.select('DISTINCT ON (users.name) *') 
    .order(users.name, users.active DESC') 

答えて

0

これは動作するはず

たぶん

User.where.not(name: nil).where.not(active: nil) 

これは人口の名前とアクティブboolean型を持つすべてのユーザーを返す3210

+0

作品を数えながらSELECT DISTINCTのために、表現BY ORDERが選択リストに表示されなければならない」として、このクエリは、関係からのアクセスの要素に失敗します' – tobmatth

+0

「関係からの要素」とはどういう意味ですか? – meshin

+0

'User.select( 'DISTINCT name')。order( 'name、active DESC')。first' – tobmatth

0

(IDは常に読み込まれます)

はその後、その上、我々はこれが唯一の私たちを与える ​​

を呼び出しますユニークな名前のレコード 最後に

.sort_by { |a| a.active ? 1 : 0 } 

アクティブなレコードを開始時にtrueにします。だから、方法は次のとおりです。このクエリに

User.where.not(name: nil).where.not(active: nil).uniq_by(:name).sort_by { |a| a.active ? 1 : 0 } 

我々はオブジェクトの数を取得するために、カウントを呼び出すことができます。


EDIT:

UNIQにuniq_by AR変化として維持するために:

User.where.not(name: nil).where.not(active: nil).uniq(name).sort_by { |a| a.active ? 1 : 0 } 
+0

uniq_byを使用するには、リレーションを配列に変換する必要がありますが、私はそれをリレーションのままにしておく必要があります。私の質問を更新しました。 – tobmatth

+0

更新された回答。 – Mark

+0

私が何かを見逃していなければ、uniqはdistinctの別名です。これは.selectが存在することを要求します(そうしないと、 'SELECT DISTINCT users。*'になります)。また、sort_byは配列 – tobmatth

0

あなたは、PostgreSQLを使用しているので、あなたがDISTINCT ONを使用することができます。ここではSQLがあります:

select distinct on (name) * from users order by name, active desc 

とアクティブレコードに:

>> User.order(name: :desc, active: :desc).select("distinct on (name) *") 
    User Load (2.5ms) SELECT distinct on (name) * FROM "users" ORDER BY "users"."name" DESC, "users"."active" DESC LIMIT $1 [["LIMIT", 11]] 
=> #<ActiveRecord::Relation [#<User id: 2, name: "bob", active: true, created_at: "2017-09-15 03:58:23", updated_at: "2017-09-15 03:58:23">, #<User id: 3, name: "alice", active: false, created_at: "2017-09-15 03:58:35", updated_at: "2017-09-15 03:58:35">]> 
+0

に変換します。それは私がすでに試したことですが、残念ながら私はその関係の.countを呼び出すことはできません。 – tobmatth

+0

あなたは正しいです、質問を読んだとき、私はそれを見逃しました。そして、 'User.corder_by_sql(User.order(name::desc、active::desc).select(" distinct on(name)* "))')を呼び出すことができますが、それは2つのクエリであり、元の質問も。 –

関連する問題