我有一个多表连接,并希望根据该连接的结果更新表。连接表既产生更新的范围(仅更新结果中应出现其work.id的那些行),也产生更新的数据(新列应设置为计算列的值)。
我已经取得了进步但却无法使其发挥作用。这是我的陈述:
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
确实更新了effort.id列,但是有两个问题:首先,它更新所有工作,而不仅仅是从查询中生成的工作,第二,它将effort.id设置为split的值。查询结果中的第一行,但我需要将每个工作量设置为关联的拆分值。
如果这是非SQL,它可能看起来像:
jt_rows.each do |jt_row|
efforts[jt_row].dropped_int = jt[jt_row].split
end
但我不知道如何在SQL中这样做。看起来这应该是一个相当普遍的问题,但经过几个小时的搜索后我才会出现问题。
我应该如何修改我的陈述以产生描述的结果?如果重要,那就是Postgres 9.5。提前感谢任何建议。
编辑:
我没有得到可行的答案,但最终用SQL和本机代码(Ruby / 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)
答案 0 :(得分:0)
在WHERE子句中使用与efforts
表和子查询相关的条件:
efforts.id = jt.id
那就是:
WHERE
((jt.distance_from_start + jt.sub_order) = max_dist)
AND
kind <> 1
AND
efforts.id = jt.id