Update文にてORDER BY句とLIMIT句を使いたくなった。

# 背景

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171559/15fd8315-2d26-47ba-16c1-86ae83751db8.png)
図のように`DB_A`から`DB_temp`,`DB_Z`へとNode-Redを使ったバケツリレーシステムがある。  

`DB_Z`へデータを格納するNode-Redは`DB_temp`の`cre_rec_date`という日付のカラムを参照して、日付の範囲を限定して`DB_Z`へとデータを格納していく。
一度に`DB_temp`全データを対象としてしまうと処理が重くなるためである。

で、ある日、`DB_Z`をぶっ壊してしまった。何も考えずにやると`DB_A`からのバケツリレーを最初からやり直せば直るのだが、`DB_temp`にはデータが残っている。ならば、`DB_temp`のデータを再利用したほうがいいだろう！
しかし、`DB_temp`の`cre_rec_date`は過去のデータとなっている。且つ、一気に`cre_rec_date`を最新日付にしてしまうと、`DB_Z`へデータ格納するNode-Redがハングアップする。（これもいかがなものかと思うがそれはここでは置いておく）

ってことで、タイトル通りのことがしたくなった。

## 環境
あまり環境に依存しないやり方ではあるが、一応記載しておく。

* PostgreSQL 13.1 (9以上であればバージョンに依存しないのではないか？）
* Windows 10 (server/client共に）

## Table作成
```
create table test_table (
  pkey_code integer not null,
  cre_rec_date timestamp with time zone not null,
  constraint test_table_PKC primary key (pkey_code)
);
```
## テストデータ作成
```
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (1, '2021/02/09 00:00:00');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (2, '2021/02/09 00:00:10');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (3, '2021/02/09 00:00:20');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (4, '2021/02/09 00:00:30');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (5, '2021/02/09 00:00:40');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (6, '2021/02/09 00:00:50');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (7, '2021/02/09 00:01:00');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (8, '2021/02/09 00:01:10');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (9, '2021/02/09 00:01:20');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (10, '2021/02/09 00:01:30');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (11, '2021/02/09 00:01:40');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (12, '2021/02/09 00:01:50');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (13, '2021/02/09 00:02:00');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (14, '2021/02/09 00:02:10');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (15, '2021/02/09 00:02:20');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (16, '2021/02/09 00:02:30');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (17, '2021/02/09 00:02:40');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (18, '2021/02/09 00:02:50');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (19, '2021/02/09 00:03:00');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (20, '2021/02/09 00:03:10');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (21, '2021/02/09 00:03:20');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (22, '2021/02/09 00:03:30');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (23, '2021/02/09 00:03:40');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (24, '2021/02/09 00:03:50');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (25, '2021/02/09 00:04:00');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (26, '2021/02/09 00:04:10');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (27, '2021/02/09 00:04:20');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (28, '2021/02/09 00:04:30');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (29, '2021/02/09 00:04:40');
INSERT INTO test.test_table(pkey_code, cre_rec_date) VALUES (30, '2021/02/09 00:04:50');
```

## UPDATE 文　（今回の肝）
```
UPDATE
  test_table
SET
  cre_rec_date = current_timestamp
WHERE
  pkey_code IN (
    SELECT
      pkey_code
    FROM
      test.test_table
    WHERE
	  cre_rec_date >= '2021/02/09 00:00:00' -- 再登録したい日付
	  AND cre_rec_date <= '2021/02/09 22:40:00' --おおよその現在時刻より少し前
    ORDER BY
      cre_rec_date
    LIMIT
      10
  );
```

このUPDATE文を実行した後`DB_Z`のNode-Redを回して、完了したら再度同様のUPDATEを実行を繰り返すと、バケツリレーの完了。

UPDATE文に直接ORDER BY句やLIMIT句が使用できないので、少しだけトリッキーなSQLになったということで、自分の備忘録も兼ねて。

アーキが悪いのではないかと思っているが、このバケツリレー仕様。。。