私は複数テーブルの結合があり、その結合の結果に基づいてテーブルを更新したいと考えています。結合テーブルは、更新の範囲(結果にeffort.idが表示される行のみ)と更新のデータ(新しい列は計算列の値に設定する必要があります)の両方を生成します。複雑なSQLクエリによって返された行を、クエリ結果のデータで更新します。
私は進歩しましたが、それを機能させることはできません。ここに私の文があります:
UPDATE
efforts
SET
dropped_int = jt.split
FROM
(
SELECT
ef.id,
s.id split,
s.kind,
s.distance_from_start,
s.sub_order,
max(s.distance_from_start + s.sub_order)
OVER (PARTITION BY ef.id) AS max_dist
FROM
split_times st
LEFT JOIN splits s ON s.id = st.split_id
LEFT JOIN efforts ef ON ef.id = st.effort_id
) jt
WHERE
((jt.distance_from_start + jt.sub_order) = max_dist)
AND
kind <> 1;
SELECTは正しいが、テーブルを結合生成:
id split kind dfs sub max_dist dropped dropped_int
403 33 2 152404 1 152405 TRUE 33
404 33 2 152404 1 152405 TRUE 33
405 31 2 143392 1 143393 TRUE 33
406 31 2 143392 1 143393 TRUE 33
407 29 2 132127 1 132128 TRUE 33
408 29 2 132127 1 132128 TRUE 33
409 29 2 132127 1 132128 TRUE 33
、実際efforts.id列を更新するが、二つの問題があるん:まず、それはすべての努力を更新し、ありませんクエリから生成されたものだけでなく、第2に、effort.idをクエリ結果の最初の行の分割値に設定しますが、関連する分割値にそれぞれの努力を設定する必要があります。
これは非SQLであれば、それは次のようになります。
jt_rows.each do |jt_row|
efforts[jt_row].dropped_int = jt[jt_row].split
end
しかし、私はSQLでそれを行う方法がわかりません。これはかなり一般的な問題であるはずですが、数時間の検索の後に私は不足しています。
記載された結果を得るために私のステートメントを変更する方法を教えてください。重要な場合、これはPostgres 9.5です。事前に感謝の意を表します。
EDIT:
私は実行可能な答えを得るが、SQLとネイティブコード(ルビー/ Railsの)の混合物でこれを解決してしまったしませんでした:
dropped_splits = SplitTime.joins(:split).joins(:effort)
.select('DISTINCT ON (efforts.id) split_times.effort_id, split_times.split_id')
.where(efforts: {dropped: true})
.order('efforts.id, splits.distance_from_start DESC, splits.sub_order DESC')
update_hash = Hash[dropped_splits.map { |x| [x.effort_id, {dropped_split_id: x.split_id, updated_at: Time.now}] }]
Effort.update(update_hash.keys, update_hash.values)
これは機能しません。私はSQLとRailsの組み合わせでこの問題を解決しました。詳細については、私のアップデートを参照してください。 – moveson