2017-03-16 17 views
1

私は最終的に私のレールモデルの1つから選択する連想、結合、順序付けなどの長いチェーンを持っています。一日の終わりに私は結果がユニークでソートされている必要があります。 SELECTステートメントで使用される列、ORDER BYなどに表示される列(これらはすべてユーザーが選択したフィルタリングオプションに基づいて変更されます)は気にしません。クエリは一意です(idに基づいて)。背景についてはPG :: InvalidColumnReference:ERROR:SELECT DISTINCTのORDER BY式が選択リストに表示されている必要があります

は、widgetsはメインテーブルであり、我々はwidget_stepsに参加している、これはRailsの3である(同社はできるだけ早くアップグレードしようとしているが、それは彼らが、現時点ではと立ち往生しているものだ)ここで

生成されているクエリとエラーです:

PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list 
LINE 1: ...completed_at" IS NULL)) ORDER BY sequential DESC, widget_s... 
                  ^
: SELECT DISTINCT "widgets".* FROM "widgets" INNER JOIN "widget_steps" ON "widget_steps"."widget_id" = "widgets"."id" INNER JOIN "widget_steps" "active_steps_widgets" ON "active_steps_widgets"."id" = "widgets"."active_widget_step_id" WHERE "widgets"."account_id" = 1 AND "widgets"."completed_at" IS NULL AND (("widgets"."sequential" = 't' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."id" = "widgets"."active_widget_step_id" AND "widget_steps"."completed_at" IS NULL) OR ("widgets"."sequential" = 'f' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."completed_at" IS NULL)) ORDER BY sequential DESC, widget_steps.name ASC LIMIT 10 OFFSET 0 
Completed 500 Internal Server Error in 52.3ms 

ActiveRecord::StatementInvalid - PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list 
LINE 1: ...completed_at" IS NULL)) ORDER BY sequential DESC, widget_s... 
                  ^
: SELECT DISTINCT "widgets".* FROM "widgets" INNER JOIN "widget_steps" ON "widget_steps"."widget_id" = "widgets"."id" INNER JOIN "widget_steps" "active_steps_widgets" ON "active_steps_widgets"."id" = "widgets"."active_widget_step_id" WHERE "widgets"."account_id" = 1 AND "widgets"."completed_at" IS NULL AND (("widgets"."sequential" = 't' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."id" = "widgets"."active_widget_step_id" AND "widget_steps"."completed_at" IS NULL) OR ("widgets"."sequential" = 'f' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."completed_at" IS NULL)) ORDER BY sequential DESC, widget_steps.name ASC LIMIT 10 OFFSET 0: 

なぜこれが問題なのですか?ポストグルはこれについてあまりにも曖昧だと思いますか?なぜこのようなクエリがMySQLではうまく動作するのですが、ポストグルが詰まるのはなぜですか?

私が試してみました:

  1. はすべて埋め込むしようとするいくつかのカスタムARELを書い
  2. を選択し、カスタムを行うことなく、チェーンの最後に.uniqを指定するチェーン
  3. の終わりに.select([everything mentioned in the order by]).uniqを指定しますこれをサブクエリで実行してから、.uniqまたは.orderを外してください(この作業を行うことはできません)
  4. ポストグレスの外で.uniqを実行しています。一部のページには1つしかありません理由は削除され、重複のそれらの上または2つの項目)
  5. あなたが選択した列のリストにwidget_steps.nameを追加する必要が
+0

「シーケンシャル」とは何ですか?それはいくつかのテーブルや他の何かの列ですか? –

+0

それはウィジェットの列です –

+0

それについて考えてみましょう:ウィジェットの1行の条件を満たす 'widget_steps'の行が2行以上ある場合、' widget_steps'の 'name'が' ORDER BY'? PostgreSQLはあなたの代わりにこれを決めるわけではないので、 'widget_steps.name'を' SELECT'節に入れて(それを 'DISTINCT'にするため) OFCでは、MySQLはこのような無関心ではありません。間違ったクエリを実行することができます。 – pozs

答えて

2

泣い:

SELECT DISTINCT "widgets".*, "widget_steps.name" FROM "widgets" INNER JOIN "widget_steps" ON "widget_steps"."widget_id" = "widgets"."id" INNER JOIN "widget_steps" "active_steps_widgets" ON "active_steps_widgets"."id" = "widgets"."active_widget_step_id" WHERE "widgets"."account_id" = 1 AND "widgets"."completed_at" IS NULL AND (("widgets"."sequential" = 't' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."id" = "widgets"."active_widget_step_id" AND "widget_steps"."completed_at" IS NULL) OR ("widgets"."sequential" = 'f' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."completed_at" IS NULL)) ORDER BY sequential DESC, widget_steps.name ASC LIMIT 10 OFFSET 0 

これはあなたのクエリのロジックを変更すべきではなく、動作します良い。これは役立つだろう

Widget.select('"widgets".*, "widget_steps.name"') 

希望:Railsでは

選択した列のリストを設定するselectの方法を使用することができます。

+0

これがうまくいった!ありがとう! ただし、widget_steps.nameはものではなく、widgets.nameを使用しなければならないことに注意してください –

関連する問題