jat*_*bat 13 sql database postgresql sql-update postgresql-9.2
我在PostgreSQL 9.2中有下表,其中包含时间戳:
GID [PK](BIGSERIAL),timestamp_mes(时间戳没有时区),time_diff(间隔)
1,2012-01-23 11时03分40秒,空
2,2012-01-23 11时03分42秒,空
3, 2012-01-23 11:03:44,空的
我添加了一个间隔列(time_diff),并希望用此查询产生的时差值填充它:
SELECT timestamp_mes - lag(timestamp_mes, 1)
over (order by timestamp_mes) as diff
from gc_entretien.trace order by timestamp_mes
Run Code Online (Sandbox Code Playgroud)
我尝试了以下查询来更新time_diff列,但没有成功:
UPDATE gc_entretien.trace set time_diff =
(SELECT trace.timestamp_mes - lag(trace.timestamp_mes, 1)
over (order by trace.timestamp_mes)
from gc_entretien.trace order by timestamp_mes);
Run Code Online (Sandbox Code Playgroud)
这会导致错误:
错误:用作表达式的子查询返回的多行
我应该如何使用时差查询生成的值更新time_diff列?
a_h*_*ame 32
像这样的东西:
with new_values as (
SELECT gid,
timestamp_mes - lag(timestamp_mes, 1) over (order by timestamp_mes) as diff
from gc_entretien.trace
)
update gc_entretien.trace as tr
set time_diff = nv.diff
from new_values nv
where nv.gid = tr.gid;
Run Code Online (Sandbox Code Playgroud)
您不能在 UPDATE 中直接使用窗口函数,因此您需要在子 SELECT 中使用它 - 您已经完成了。但是,您尝试在 UPDATE 中使用该子 SELECT 的方式是无效的语法。您需要将 sub-SELECT 放在更新的 FROM 子句中,如此处的 Postgres 文档所述:
http://www.postgresql.org/docs/9.2/static/sql-update.html
您想要做的正确语法是:
UPDATE gc_entretien.trace t
SET time_diff = subquery.diff
FROM (SELECT {{SomeUniqueId}},
timestamp_mes - lag(timestamp_mes, 1) over (order by timestamp_mes) as diff
FROM gc_entretien.trace order by timestamp_mes) AS subquery
WHERE t.{{SomeUniqueId}} = subquery.{{SomeUniqueId}}
Run Code Online (Sandbox Code Playgroud)
显然,您需要用我写过的行的某些唯一 ID 的列名替换 {{SomeUniqueId}}