从cte(postgresql)更新结果

sib*_*ert 13 sql postgresql postgresql-9.1

如果有任何记录是较早的日期,我想更新工作日期.尝试使用CTE来实现这一目标:

CREATE TABLE job
    (jobid int4, jobdate date);

INSERT INTO job
    (jobid, jobdate)
VALUES
    (1, '2016-02-01'),
    (2, '2016-02-01'),
    (3, '2016-02-01'),
    (4, '2016-02-01')
;

CREATE TABLE rec
    (recid int4, recjob int4, recdate date);

INSERT INTO rec
    (recid, recjob, recdate)
VALUES
    (1,1,'2016-02-01'),
    (2,2,'2016-01-01'),
    (3,3,'2016-02-01'),
    (4,4,'2016-02-01')
;
Run Code Online (Sandbox Code Playgroud)

工作号码2的记录日期早于工作日期.所以我想用记录日期更新这份工作.

WITH      cte AS
          (SELECT jobid,least(min(recdate),jobdate)
FROM      job
LEFT JOIN rec ON recjob=jobid
GROUP BY  jobid,jobdate
HAVING    least(min(recdate),jobdate)<jobdate)
Run Code Online (Sandbox Code Playgroud)

选择cte显示正确的作业2应该更新

SELECT * FROM cte
Run Code Online (Sandbox Code Playgroud)

但是更新会产生错误:缺少表"cte"的FROM子句条目

UPDATE job 
SET    jobdate=cte.date 
WHERE  jobid IN (SELECT jobid FROM cte)
Run Code Online (Sandbox Code Playgroud)

SQLFiddle:http://sqlfiddle.com/#!15/e9ae6/8

我从未使用过cte和更新,所以我需要一些帮助才能理解这一点.

TIA,

Wil*_*iam 29

尝试UPDATE使用以下语法;

UPDATE job
SET jobdate = cte.date
FROM cte
WHERE job.jobid = cte.jobid
Run Code Online (Sandbox Code Playgroud)

  • 请注意,有时值得尝试使用 CTE,如 simPod 下面的答案所述。在某些(大)表上,使用其中一个而不是另一个可以产生巨大的性能优势。 (3认同)

sim*_*Pod 9

语法如下:

WITH cte AS (
    SELECT * FROM ...
)
UPDATE table_to_update
SET column_from_table_to_update = cte.some_column
FROM cte
WHERE table_to_update.id = cte.id
Run Code Online (Sandbox Code Playgroud)