BEGIN; ALTER TABLE employee_kandangs DROP CONSTRAINT IF EXISTS fk_employee_kandangs_kandang; ALTER TABLE employee_kandangs DROP CONSTRAINT IF EXISTS uq_employee_kandangs; CREATE TEMP TABLE tmp_kandang_group_to_kandang_map ( kandang_group_id BIGINT PRIMARY KEY, kandang_id BIGINT NOT NULL ) ON COMMIT DROP; INSERT INTO tmp_kandang_group_to_kandang_map (kandang_group_id, kandang_id) SELECT k.kandang_group_id, MIN(k.id) AS kandang_id FROM kandangs k WHERE k.kandang_group_id IS NOT NULL GROUP BY k.kandang_group_id; DO $$ BEGIN IF EXISTS ( SELECT 1 FROM employee_kandangs ek LEFT JOIN tmp_kandang_group_to_kandang_map m ON m.kandang_group_id = ek.kandang_id WHERE m.kandang_id IS NULL ) THEN RAISE EXCEPTION 'Cannot rollback employee_kandangs migration: kandang_group_id has no kandang mapping'; END IF; END $$; UPDATE employee_kandangs ek SET kandang_id = m.kandang_id, updated_at = NOW() FROM tmp_kandang_group_to_kandang_map m WHERE m.kandang_group_id = ek.kandang_id; DELETE FROM employee_kandangs ek1 USING employee_kandangs ek2 WHERE ek1.id > ek2.id AND ek1.employee_id = ek2.employee_id AND ek1.kandang_id = ek2.kandang_id; ALTER TABLE employee_kandangs ADD CONSTRAINT fk_employee_kandangs_kandang FOREIGN KEY (kandang_id) REFERENCES kandangs (id) ON DELETE CASCADE; ALTER TABLE employee_kandangs ADD CONSTRAINT uq_employee_kandangs UNIQUE (employee_id, kandang_id); COMMIT;