テーブルの複数の列を同じテーブルの別の行の値で更新しようとしています。
CREATE TEMP TABLE person (
pid INT
, name VARCHAR(40)
, dob DATE
, younger_sibling_name VARCHAR(40)
, younger_sibling_dob DATE
);
INSERT INTO person VALUES (pid, name, dob)
(1, 'John' , '1980-01-05')
, (2, 'Jimmy', '1975-04-25')
, (3, 'Sarah', '2004-02-10')
, (4, 'Frank', '1934-12-12')
;
タスクは、年齢が最も近いが、それ以上の年齢や同じ年齢ではない人の名前と誕生日をyounger_sibling_name
入力することです。younger_sibling_dob
これは、相関サブクエリで使用するレコードを決定する値であるため、若い兄弟をdob
簡単に設定できます(これはその例だと思いますか?):
UPDATE person SET younger_sibling_dob = (
SELECT MAX(dob)
FROM person AS sibling
WHERE sibling.dob < person.dob);
name
?を取得する方法がわかりません。
これの実際のクエリは、MAXの選択ごとに100〜500のグループで約100万行にわたって実行されるため、パフォーマンスが問題になります。
編集
多くの異なるアプローチを試した後、私はこれを決定しました。これは、中間結果でデータを検証でき、ロジックが何であるかの意図を示し、適切に実行できることのバランスが取れていると思います。
WITH sibling AS (
SELECT person.pid, sibling.dob, sibling.name,
row_number() OVER (PARTITION BY person.pid
ORDER BY sibling.dob DESC) AS age_closeness
FROM person
JOIN person AS sibling ON sibling.dob < person.dob
)
UPDATE person
SET younger_sibling_name = sibling.name
,younger_sibling_dob = sibling.dob
FROM sibling
WHERE person.pid = sibling.pid
AND sibling.age_closeness = 1;
SELECT * FROM person ORDER BY dob;