LINUX.ORG.RU

История изменений

Исправление 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