web-dev-qa-db-ja.com

cte(postgresql)の結果で更新

以前の日付のレコードがある場合は、ジョブの日付を更新したい。これを達成するために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')
;

ジョブ番号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)

Cteを選択すると、ジョブ2を更新する必要があることが正しく表示されます

SELECT * FROM cte

しかし、更新するとエラーが発生します。テーブル "cte"のFROM句エントリがありません

UPDATE job 
SET    jobdate=cte.date 
WHERE  jobid IN (SELECT jobid FROM cte)

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

私はcteをupdateで使用したことがないので、これを理解するために助けが必要です。

TIA、

13
sibert

次の構文でUPDATEを試してください。

UPDATE job
SET jobdate = cte.date
FROM cte
WHERE job.jobid = cte.jobid
29
William

構文は次のとおりです。

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
8
simPod

Cteはテーブルです。 1つの解決策は、次のように選択します。

WITH      cte AS
          (SELECT jobid,least(min(recdate),jobdate)as date
FROM      job
LEFT JOIN rec ON recjob=jobid
GROUP BY  jobid,jobdate
HAVING    least(min(recdate),jobdate)<jobdate)

UPDATE    job 
SET       jobdate=(SELECT date from cte)
WHERE     jobid IN (SELECT jobid from cte)

または、UPDATE ... FROM構文を使用します

1
firetonton