我有两张桌子:
[Table container]
id int
<some more fields>
latest_measurement int
[Table measurement]
id int
container_id int
unixtime bigint
现在,我想根据测量表中的最新测量值更新传感器表latest_measurement
列。我准备了子查询以返回每sensor_id
的最新测量值,这有效:
SELECT m.fill_level
from measurement m
inner join (
select m.container_id, MAX(m.unixtime) as maxdate from measurement m GROUP BY container_id
) m2
on m2.container_id = m.container_id
where m.unixtime = m2.maxdate
但是,如果我在我的更新语句中使用此查询,如下所示,它将失败并出现异常:
UPDATE container
SET latest_fill_level = (
SELECT m.fill_level
from measurement m
inner join (
select m.container_id, MAX(m.unixtime) as maxdate from measurement m GROUP BY container_id
) m2
on m2.container_id = m.container_id
where m.unixtime = m2.maxdate
and container.id = m.container_id)
最后,这是例外:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
如何编写一个更新语句,该语句可以从产生多个值的SELECT语句中使用各自的值更新多行?
答案 0 :(得分:2)
您的子查询不会破坏关系。如果使用最新的unixtime
进行多次测量,则会返回多行。由于SQL Server无法知道应该使用哪一行来更新列,因此会引发Subquery returned more than 1 value.
错误。
您可以使用row_number()
打破关系:
update c
set latest_measurement = m.fill_level
from container c
join (
select row_number() over (
partition by container_id
order by unixtime desc) as rn
, *
from measurement
) m
on c.id = m.container_id
and m.rn = 1 -- Latest measurement only
或者,您可以使用top 1
子句打破关系:
update container
set latest_measurement =
(
select top 1 fill_level
from measurement m
where container.id = m.container_id
order by
unixtime desc
)