Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating a column with the results of a query in PostgreSQL

I have the following table in PostgreSQL 9.2 which contains time stamps:

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, empty

I have added a interval column (time_diff) and would like to fill it with time difference values resulting from this query:

SELECT timestamp_mes - lag(timestamp_mes, 1) 
over (order by timestamp_mes) as diff
from gc_entretien.trace order by timestamp_mes

I have tried the following query to update the time_diff column, with no success:

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);

This results in an error:

ERROR: more than one row returned by a subquery used as an expression

How should I proceed to update the time_diff column with the values resulting from the time difference query?

like image 599
jatobat Avatar asked Dec 07 '12 17:12

jatobat


People also ask

Which query will UPDATE the value of a column?

The UPDATE statement in SQL is used to update the data of an existing table in database. We can update single columns as well as multiple columns using UPDATE statement as per our requirement. UPDATE table_name SET column1 = value1, column2 = value2,...

How do you UPDATE a table with a query?

Open the database that contains the records you want to update. On the Create tab, in the Queries group, click Query Design. Click the Tables tab. Select the table or tables that contain the records that you want to update, click Add, and then click Close.

How do I populate a column in PostgreSQL?

Syntax. The syntax to add a column in a table in PostgreSQL (using the ALTER TABLE statement) is: ALTER TABLE table_name ADD new_column_name column_definition; table_name.


3 Answers

Something like this:

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;
like image 66
a_horse_with_no_name Avatar answered Oct 26 '22 23:10

a_horse_with_no_name


You can't directly use a window function in an UPDATE, so you instead need to use it in a sub-SELECT - which you have done. However, the way you've tried to use that sub-SELECT in your UPDATE is not valid syntax. You need to put the sub-SELECT in the FROM clause of your update, as explained by the Postgres docs here:

http://www.postgresql.org/docs/9.2/static/sql-update.html

The correct syntax for what you want to do is:

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

Obviously, you'll need to substitute in the column name of some unique id that your rows have where I've written {{SomeUniqueId}}

like image 35
Mark Amery Avatar answered Oct 27 '22 01:10

Mark Amery


Actually you are getting this error because your subquery returns multiple result,

I am not able to understand your query so,

I will give you an example to solve it,

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

Here :-your_operation means the logic of finding time difference,

like image 1
Hunter Avatar answered Oct 27 '22 01:10

Hunter