70

ActionView::Template::Error (PG::Error: ERROR: SELECT DISTINCT の場合、ORDER BY 式は選択リストに表示される必要があります

イベント Web サイトを作成していて、レンダリングされた rsvps をイベントの開始時間で並べ替えようとしています。RSVPS がたくさんあるので、それらを個別にグループ化していますが、ここ数日、このエラーが PG に表示されずに結果をソートするのに苦労しています。このトピックに関する以前の質問のいくつかを見てきましたが、まだかなり迷っています。どうすればこれを機能させることができますか? どうもありがとう!

@rsvps = Rsvp.where(:voter_id => current_user.following.collect {|f| f["id"]}, :status => 'going').where("start_time > ? AND start_time < ?", Time.now, Time.now + 1.month).order("count_all desc").count(:group => :event_id).collect { |f| f[0] }

<%= render :partial => 'rsvps/rsvp', :collection => Rsvp.where(:event_id => @rsvps).select("DISTINCT(event_id)").order('start_time asc') %>
4

5 に答える 5

82

ORDER BY 句は、DISTINCT が適用された後にのみ適用できます。DISTINCT 操作では SELECT ステートメントのフィールドのみが考慮されるため、ORDER BY で使用できるのはそれらのフィールドだけです。

論理的には、event_id 値の個別のリストが必要な場合は、それらが発生する順序は関係ありません。順序が問題になる場合は、順序のコンテキストが存在するように、SELECT リストに start_time を追加する必要があります。

また、これら 2 つの SELECT 句は同等ではないため、注意してください。

SELECT DISTINCT(event_id, start_time) FROM ...

SELECT DISTINCT event_id, start_time FROM ...

2 つ目は、必要なフォームです。1 つ目は、ROW コンストラクト (内部にタプルを持つ単一の列) として表されるデータを含む一連のレコードを返します。2 番目は、データ出力の通常の列を返します。ROW コンストラクトは 1 つの列にすぎないため、縮小される単一列の場合にのみ期待どおりに機能します。

于 2012-10-02T15:25:14.507 に答える
2

start_time 列を使用しているため、PostgreSQL のウィンドウ関数の1 つである row_number() を使用してスタックすることができます。

  • 行の値が最初の start_time であると想定している場合は、start_time の順序

    (SELECT event_id ,ROW_NUMBER() OVER(PARTITION BY event_id ORDER BY start_time) AS first_row FROM Rsvp) から event_id を選択 (first_row = 1)

  • 最後の start_time の行の値が必要な場合は、start_time の逆順

    (SELECT event_id ,ROW_NUMBER() OVER(PARTITION BY event_id ORDER BY start_time desc) AS last_row FROM Rsvp) から event_id を選択 (last_row = 1)

要件に応じて、さまざまなウィンドウ関数を使用することもできます。

于 2019-06-24T09:46:57.117 に答える