15

我在 PostgreSQL 9.2 中有下表,其中包含时间戳:

gid [PK] (bigserial), timestamp_mes (timestamp without time zone), time_diff (interval)
1, 2012-01-23 11:03:40, empty
2, 2012-01-23 11:03:42, empty
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

我尝试了以下查询来更新 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);

这会导致错误:

错误:用作表达式的子查询返回多行

我应该如何继续使用时差查询产生的值更新 time_diff 列?

4

3 回答 3

38

像这样的东西:

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;
于 2012-12-07T19:32:09.700 回答
5

您不能直接在 UPDATE 中使用窗口函数,因此您需要在子 SELECT 中使用它 - 您已经完成了。但是,您尝试在 UPDATE 中使用该子 SELECT 的方式不是有效的语法。您需要将 sub-SELECT 放在更新的 FROM 子句中,如 Postgres docs here 所述:

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}}

显然,您需要用我写的行所具有的某个唯一 id 的列名替换{{SomeUniqueId}}

于 2012-12-07T19:36:23.100 回答
1

实际上,您收到此错误是因为您的子查询返回多个结果,

我无法理解您的查询,所以,

我给你一个例子来解决它,

update table t1 set time_diff= select *your_operation* from table t2 where t1.id=t2.id

这里:-your_operation 表示查找时差的逻辑,

于 2012-12-07T17:30:17.977 回答