【问题标题】:Update multiple columns in a table from another tables data including nulls从另一个表数据更新表中的多个列,包括空值
【发布时间】:2017-03-08 22:37:03
【问题描述】:

我有两个包含 6 列的表,在一个表(我要更新的那个)中,前三列已经填充,另外三列是我刚刚创建的,所以它们是空的。

汇总表

Number, ID, height, weight, volume, density
1        1     5       
2        2     5
3        3     12

我有另一个完全填充的表,其中使用了相同的 ID,但其他数据波动并且没有高度

每日餐桌

Number, ID, name, weight, volume, density
1       1    c3     23               10
2       2    c17    24.2    1        5
3       3    c12    22      2        6
4       1    c3     21      2
5       2    c17    25               8

我想从 Daily 表中获取最后的重量、体积、密度值,并使用它们来填充 Summary 表中的这些列。两张表都有数千个条目,每天接近一百万个。

结果应该是汇总表更改

Number, ID, height, weight, volume, density
1       1     5      21      2   
2       2     5      25               8
3       3     12     22      2        6

我可以使用从this question 获得的信息一点一点地完成它,但我想一次性完成。 请帮忙。

【问题讨论】:

  • 如何识别日表中的“最后”行?我没有看到任何时间戳或类似的东西
  • @a_horse_with_no_name 它们是编号的行,抱歉现在应该是六列我明白你的意思了,我会编辑

标签: sql postgresql


【解决方案1】:

类似这样的:

update summary 
  set weight = t.weight,
      volume = t.volume, 
      density = t.density
from (
  select distinct on (id) id, weight, volume, density
  from daily
  order by id, number desc
) t
where t.id = summary.id;

内部选择将只返回每日表中每个 id 具有最高“数字”的行。其他解决方法见

在线示例:http://rextester.com/AWT29305

【讨论】:

  • 非常适合我的需求,又好又简单
【解决方案2】:

试试这个:

with Daily as (
select d.number, d.Id, d.weight, d.volume, d.density 
From  daily d 
join (select id, max(number) from daily group by ID) d2 on d.number = d2.number
)
update Summary
set weight = d2.weight
, volume = d2.volume
, density = d2.density
from Daily d2
where id = d2.id
and
(weight<> d2.weight OR
volume <> d2.volume OR
density <> d2.density)
)

这应该确保您获得每个 id 的正确最新记录,并且只获得那些需要更新的记录。

【讨论】:

  • 我花了一段时间才明白这一点,但效果很好
【解决方案3】:

您可以使用窗口函数来获取每日表中每个 ID 的最新条目。我已经在 SQL Server 中对此进行了测试,但我相信 postgres 的语法在这种情况下是相同的。

With LatestDaily As
(
  select *
  from (
    Select RANK() OVER (Partition By ID ORDER BY Number DESC) as r, *
    From Daily
  ) t
  where t.r = 1
)
Update summary s
   Set Weight = d.Weight, Volume = d.Volume, Density = d.Density
From LatestDaily d 
where s.ID = d.ID;

【讨论】:

  • Postgres 在末尾需要;,而不是在开头。当使用 distinct on() 而不是窗口函数时,Postgres 中的“greatest-n-per-group”问题通常更快。而 update 的连接语法在 Postgres 中是不同的。您应该from 子句中重复目标表。
  • 好收获。谢谢!我想知道 sql server 是否有相当于 postgres 的 distinct on()。这是一个简洁的功能。
  • 我冒昧地修复了您语句中的语法错误。
【解决方案4】:

更新摘要 SET weight = _weight, volume = _volume, density =_density 从 ( SELECT ID _ID、重量_重量、体积_体积、密度_密度 来自详细信息 WHERE Number IN (SELECT MAX(Number) FROM Details GROUP BY ID) ) WHERE ID = _ID

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-18
    • 1970-01-01
    • 2021-10-16
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多