Files
job-search/internal/store/migrations/00010_unique_cpv_codes.sql
T

61 lines
1.9 KiB
SQL

-- +goose Up
-- +goose StatementBegin
-- A CPV code has one official description, so it is now one row whatever
-- description it arrives with: EU Supply cuts descriptions to 64 characters,
-- which made a second row for each code it sent. The duplicates are merged
-- into the row with the longest description, and the upsert keeps the
-- longest from now on. Other schemes still get a row per distinct content.
-- The row each CPV row merges into.
CREATE TEMP TABLE "cpv_merge" AS
SELECT
"c"."id" AS "id",
(
SELECT "k"."id" FROM "classification_codes" "k"
WHERE "k"."is_cpv" AND "k"."code" = "c"."code"
ORDER BY length("k"."classification") DESC, "k"."id"
LIMIT 1
) AS "keep_id"
FROM "classification_codes" "c"
WHERE "c"."is_cpv";
-- An opportunity linked to both rows keeps only its link to the kept one.
DELETE FROM "opportunity_classifications"
WHERE "classification_id" IN (
SELECT "id" FROM "cpv_merge" WHERE "id" <> "keep_id"
)
AND EXISTS (
SELECT 1
FROM "cpv_merge" "m"
JOIN "opportunity_classifications" "kept"
ON "kept"."classification_id" = "m"."keep_id"
WHERE "m"."id" = "opportunity_classifications"."classification_id"
AND "kept"."opportunity_uuid"
= "opportunity_classifications"."opportunity_uuid"
);
UPDATE "opportunity_classifications"
SET "classification_id" = (
SELECT "keep_id" FROM "cpv_merge"
WHERE "id" = "opportunity_classifications"."classification_id"
)
WHERE "classification_id" IN (
SELECT "id" FROM "cpv_merge" WHERE "id" <> "keep_id"
);
DELETE FROM "classification_codes"
WHERE "id" IN (SELECT "id" FROM "cpv_merge" WHERE "id" <> "keep_id");
DROP TABLE "cpv_merge";
CREATE UNIQUE INDEX IF NOT EXISTS "classification_codes_cpv"
ON "classification_codes" ("code") WHERE "is_cpv";
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
-- The merged duplicates aren't restored: they only differed by a cut-off
-- description.
DROP INDEX IF EXISTS "classification_codes_cpv";
-- +goose StatementEnd