0

PostgreSQL クエリで厄介な問題に遭遇しました。これは私のローカル開発環境で動作します:

SELECT distinct (user_id) user_id, created_at, is_goodday 
FROM table 
WHERE ((created_at >= '2011-07-01 00:00:00') AND user_id = 95 
AND (created_at < '2011-08-01 00:00:00')) 
ORDER BY user_id, created_at ASC;

...しかし、私のQAサーバー(Heroku上にあります)で次のエラーが発生します:

PGError: ERROR:  syntax error at or near "user_id"
LINE 1: SELECT distinct (user_id) user_id, created_at,
                                  ^ 

これはなぜですか?

その他の関連情報:

フィールド名を一重引用符と二重引用符で囲んでみました

これは Rails 3 アプリですが、私はこの SQL raw を使用しています。つまり、ActiveRecord マジックはありません。

Postgres のローカル バージョンは Mac で 9.0.4 ですが、Heroku が使用しているバージョンがわかりません

4

3 に答える 3

1

あなたのコメントによると、そのクエリの標準 PostgreSQL バージョンは次のようになります。

SELECT user_id, created_at, is_goodday
FROM table
WHERE created_at >= '2011-07-01 00:00:00'
  AND created_at <  '2011-08-01 00:00:00'
  AND user_id     = 95
ORDER BY created_at DESC, id DESC
LIMIT 1

ORDER BY には必要ありませんuser_id。なぜなら、ORDER BY で最新のものを一番上に置きuser_id = 95たいからです。次に、結果セットの最初の行だけをスライスします。GROUP BY は、一意性を強制するために使用できます。または、集計関数のために物事をグループ化する必要があるが、ORDER BY と LIMIT を介して一意性を取得でき、集計をORDER BY (つまり、ORDER BY が自動的に行うため、MAX は必要ありません)。created_at DESCcreated_atLIMIT 1

WHERE にあるので、SELECTuser_id = 95は必要ありませんがuser_id、Ruby ランドでの作業が容易になる場合はそのままにしておくことができます。

同じエントリが複数存在する可能性があるため、ORDER BY にcreated_atを追加しid DESCて、PostgreSQL に最大のものを選択させましたid。彼らが本当にあなたを捕まえようとしていて、バグが間違いなくあなたを捕まえようとしているときに、妄想的であることは何も悪いことではありません.

DESCまた、 ORDER BY で最高値を一番上に取得したい場合ASCは、最低値を一番上に置きます。タイムスタンプが新しいほど、タイムスタンプが高くなります。

一般に、次の理由により、GROUP BY と SELECTは一致する必要があります。

GROUP BY が存在する場合、グループ化されていない列に対して複数の値が返される可能性があるため、集計関数内を除き、SELECT リスト式がグループ化されていない列を参照することは無効です。

ただし、GROUP BY はまったく必要ないため、ここでは問題ありません。使用している PostgreSQL のバージョンと一致するように、8.3 バージョンのドキュメントにリンクしました。

これを行うにはおそらく他にもさまざまな方法がありますが、これはおそらくあなたが得ようとしているのと同じくらい簡単で明確です。

于 2011-07-22T21:41:13.810 に答える
0

DISTINCT ON を使用しています (ON を記述せずに)。おそらく、あなたはONを書くべきです。おそらく、あなたのpostgreサーバーは機能が実装される前のものです(今ではかなり古いものです)。

他のすべてが失敗した場合は、いつでも GROUP BY を使用してそれを行うことができます...

于 2011-07-22T18:29:49.070 に答える
0

のように user_id に引用符を付けますuser_id = '95'。あなたのクエリは

SELECT distinct (user_id) as uid, created_at, is_goodday  FROM table  WHERE 
((created_at >= '2011-07-01 00:00:00') AND user_id = '95'  AND (created_at < '2011-08-01 00:00:00'))  ORDER BY user_id, created_at ASC;   
于 2011-07-22T18:18:36.357 に答える