История изменений
Исправление Toxo2, (текущая версия) :
По заголовку можно было бы подумать про https://github.com/ossc-db/pg_hint_plan
Только он не будет работать на CTE. Да и удачное применение этих хинтов - очень, очень редкий случай. ПГ обычно сам хорошо разбирается, что и как ему сканировать. Один раз видел, как с JOIN ему удачно помогли. На сканирование - ни разу не видел.
По тексту задачи и вашему запросу - мне кажется у вас тут совсем не то происходит, что вы описываете. Или я что-то не понимаю, или у вас NeedDelete вообще никогда не наступит для записи с «User» полностью совпадающим с запрошенными пользователями. Вы же каждый раз исключаете из массива следующего пользователя. У вас и получатся две записи - в одной первый исключен, во второй другой исключен. Разве это то, что вы хотите реализовать?
Попробовал написать в вашем стиле, и в ваших терминах что-то такое:
WITH cte_user AS (
SELECT DISTINCT UNNEST(ARRAY['27672','6145']) AS "Id"
)
,cte_sel AS (
SELECT
d."@Id"
,d."Account"
,(
SELECT array_agg("Id")
FROM UNNEST(d."User") ou("Id")
WHERE NOT EXISTS (SELECT FROM cte_user cu WHERE cu."Id" = ou."Id")
) AS "NewUser"
FROM
"Documents" d
WHERE
d."Account" = 4777912
)
,cte_upd AS (
UPDATE "Documents" d
SET "User" = s."NewUser"
FROM cte_sel s
WHERE
d."@Id" = s."@Id"
AND s."NewUser" IS NOT NULL
)
DELETE FROM "Documents" d
USING cte_sel s
WHERE
d."@Id" = s."@Id"
AND s."NewUser" IS NULL
Исходная версия Toxo2, :
По заголовку можно было бы подумать про https://github.com/ossc-db/pg_hint_plan
Только он не будет работать на CTE. Да и удачное применение этих хинтов - очень, очень редкий случай. ПГ обычно сам хорошо разбирается, что и как ему сканировать. Один раз видел, как с JOIN ему удачно помогли. На сканирование - ни разу не видел.
По тексту задачи и вашему запросу - мне кажется у вас тут совсем не то происходит, что вы описываете. Или я что-то не понимаю, или у вас NeedDelete вообще никогда не наступит. Вы же каждый раз исключаете из массива следующего пользователя. У вас и получатся две записи - в одной первый исключен, во второй другой исключен. Разве это то, что вы хотите реализовть?
Попробовал написать в вашем стиле, и в ваших терминах что-то такое:
WITH cte_user AS (
SELECT DISTINCT UNNEST(ARRAY['27672','6145']) AS "Id"
)
,cte_sel AS (
SELECT
d."@Id"
,d."Account"
,(
SELECT array_agg("Id")
FROM UNNEST(d."User") ou("Id")
WHERE NOT EXISTS (SELECT FROM cte_user cu WHERE cu."Id" = ou."Id")
) AS "NewUser"
FROM
"Documents" d
WHERE
d."Account" = 4777912
)
,cte_upd AS (
UPDATE "Documents" d
SET "User" = s."NewUser"
FROM cte_sel s
WHERE
d."@Id" = s."@Id"
AND s."NewUser" IS NOT NULL
)
DELETE FROM "Documents" d
USING cte_sel s
WHERE
d."@Id" = s."@Id"
AND s."NewUser" IS NULL