2012-03-18 7 views
14

は、私は次のクエリがありますRails 3、ActiveRecord、PostgreSQL - ".uniq"コマンドが機能しない?

Article.joins(:themes => [:users]).where(["articles.user_id != ?", current_user.id]).order("Random()").limit(15).uniq 

をし、私がそうエラーがなくなって

Article.joins(:themes => [:users]).where(["articles.user_id != ?", current_user.id]).order("Random()").limit(15)#.uniq 

に元のクエリを更新エラー

PG::Error: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list 
LINE 1: ...s"."user_id" WHERE (articles.user_id != 1) ORDER BY Random() L... 

を与えます... MySQL .uniqでは、PostgreSQLでは動作しません。存在する代替手段はありますか?

+0

'uniq'を使用したクエリが異なる結果を返すことは確かですか?各バリアントの実際のSQLクエリを表示してください( 'sql'メソッドを使用してください)。 – taro

+0

私は確信しています。私はMySQLデータベースでこのクエリを使用したので、 '.uniq'を使わないと同じ行が返されますが、' .uniq'は常に一意の行です。 PostgreSQLで '.uniq'を使用すると、' .uniq'を使わないと上記のエラーが出ますので、エラーはなくなりますが、DBからも同じ行が得られます。 – user984621

答えて

30

エラー状態はfor SELECT DISTINCT, ORDER BY expressions must appear in select listです。 したがって、注文する句を明示的に選択する必要があります。

これは例ですが、これはあなたのケースに似ていますが、少し一般化しています。だから、

Article.select('articles.*, RANDOM()') 
     .joins(:users) 
     .where(:column => 'whatever') 
     .order('Random()') 
     .uniq 
     .limit(15) 

、明示的.select()を使用して(この場合はRANDOM()で)あなたのORDER BY句が含まれます。上記のように、クエリがArticle属性を返すためには、明示的に選択する必要があります。

私はこれが役立つことを望みます。幸運

+2

なぜ注文したものをpostgresqlの最初の場所にあるselect節に追加しなければならないのですか?結合を使用している場合、select句で明示的に宣言することなく(特にselect句は返される列を制限するため)、何を並べ替えるべきかを知るには、sqlが十分にスマートでなければなりません。 – JohnMerlino

+0

'RANDOM()'をインクルードすると、完全にユニークな値を考慮しているので、 'DISTINCT'を完全に否定しませんか?そして、あなたは、最初に 'DISTINCT'を使用しなかったかのように、重複レコードで終わるでしょうか? –

1

.uniqメソッドがSQLのDISTINCT句に変換されているとします。 PostgreSQLは厄介です(MySQLより選択肢が多い) - DISTINCTを使用しているときに選択リストのすべてのフィールドがORDER_BY(およびGROUP_BY)節になければなりません。

あなたがしようとしていることは少し不明です(ランダムな注文ですか?)。送信された完全なSQLを送信することに加えて、あなたの目的を説明することができれば、代替案を見つける際に役立つかもしれません。

+0

あなたは正しいかもしれませんが、 'DISTINCT'句の上のクエリに統合するためのエレガントな方法がありますか?私の現在のクエリは "かなり短い"ですが、 'find_by_sql'を使うことができますし、' DISTINCT'句を直接設定することもできますが、この場合クエリはもっと​​大きくなります。 – user984621

0

私は100.1%の作業とテスト済みのアプリケーションを3.1.1から3.2.7にアップグレードしましたが、今この同じPG :: Errorを持っています。私はカンカン...

@users = User.accessible_by(current_ability).ORDER( 'LNAMEのASC')を使用しています。UNIQ

.uniqを削除

は、問題を解決し、それが必要ではなかったですとにかくこの簡単なクエリのために。

3.1.1と3.2.7の間の変更点を調べて、何が原因で破壊されたのかを確認します。

2

さらに多くの例でスレッドを充実させるだけで、クエリにネストされたリレーションがある場合は、次のステートメントで試すことができます。与えられた例では

Person.find(params[:id]).cars.select('cars.*, lower(cars.name)').order("lower(cars.name) ASC") 

、あなたはモデル名(アウディ、フェラーリ、ポルシェ)

順与えられた人のためにすべての車を求めている私は、これは良い方法だとは思いません、リレーショナル(データベース)のやり方ではなく、オブジェクトやコレクションで考えるこのような状況に対処するのに役立ちます。

ありがとうございます!