Reputation: 57
I have a table that contains more than 16,000,000 records. Each record has a primary key (formed by five fields "tsid, plisid, plifc, plisc, dt"), and two counter fields ("icount, aicount").
There is a relation between some of the records in the table.
To simplify the problem let's say we have only these two records
tsid, plisid, plifc, plisc, dt, icount, aicount
10 1 0 0 0 2 2
11 1 0 0 0 7 0
The requirement:
I want to update the "aicount" field in the second record to be 9 (i.e. "icount" in the second record + "aicount" in the first record). The relation between the first and second record is that they have the same values in (plisid, plifc, plisc, dt), and the tsid value of the second record == the tsid of the first record + 1
The desired result after the update is:
tsid, plisid, plifc, plisc, dt, icount, aicount
10 1 0 0 0 2 2
11 1 0 0 0 7 9
I tried this SQL statement in PostgreSQL but I got a syntax error "ERROR: syntax error at or near "SELECT" Position: 59"
UPDATE table1 SET
table1.aicount = table1.icount + SELECT COALESCE( (SELECT CASE
WHEN table1temp.aicount IS NULL
THEN 0
ELSE table1temp.aicount
END
FROM table1 table1temp
WHERE table1temp.tsid = table1.tsid - 1
AND table1temp.plisid = table1.plisid
AND table1temp.plifc = table1.plifc
AND table1temp.plisc = table1.plisc
AND table1temp.dt = table1.dt), 0)
WHERE table1.tsid = 10;
What is the wrong in the statement above? Any idea or suggestions?
Upvotes: 1
Views: 180
Reputation: 364
Try the following query-:
update T
set aicount=mm.m
from(
select sum(iCount) over (partition by plisid,plifc,plisc,dt order by tsid) m from T
) mm
SQL Server
Upvotes: 1
Reputation: 46219
The error caused because you couldn't use select
subquery to add an update column.
You seem to want to get the number, which this row icount
number add with last recorded aicount
number
I would use LAG function to get last recorded aicount
number in subquery then update the number.
There are three parameters in LAG
function.
null
lag(value any [, offset integer [, default any ]])
returns value evaluated at the row that is offset rows after the current row within the partition; if there is no such row, instead return default. Both offset and default are evaluated with respect to the current row. If omitted, offset defaults to 1 and default to null
CREATE TABLE T( tsid int, plisid int, plifc int, plisc int, dt int, icount int, aicount int );
INSERT INTO T VALUES (10,1,0,0,0,2,2);
INSERT INTO T VALUES (11,1,0,0,0,7,0);
UPDATE T
SET aicount = t1.totle
FROM
(
SELECT *,(LAG(aicount,1,0) over(order by tsid) + icount) totle
FROM T
) t1
WHERE
T.tsid = t1.tsid
AND T.plisid = t1.plisid
AND T.plifc = t1.plifc
AND T.plisc = t1.plisc
AND T.dt = t1.dt
Query 1:
SELECT * FROM T
| tsid | plisid | plifc | plisc | dt | icount | aicount |
|------|--------|-------|-------|----|--------|---------|
| 10 | 1 | 0 | 0 | 0 | 2 | 2 |
| 11 | 1 | 0 | 0 | 0 | 7 | 9 |
Upvotes: 1