使用查询结果

时间:2016-05-13 09:27:53

标签: postgresql join sql-update

我有一个多表连接,并希望根据该连接的结果更新表。连接表既产生更新的范围(仅更新结果中应出现其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)

1 个答案:

答案 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