从另一个表数据更新表中的多个列,包括空值
Posted
技术标签:
【中文标题】从另一个表数据更新表中的多个列,包括空值【英文标题】: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 它们是编号的行,抱歉现在应该是六列我明白你的意思了,我会编辑 【参考方案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 具有最高“数字”的行。其他解决方法见greatest-n-per-group
在线示例: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
【讨论】:
以上是关于从另一个表数据更新表中的多个列,包括空值的主要内容,如果未能解决你的问题,请参考以下文章