WITH
позволяет определить «временные таблицы» для использования в запросе SELECT
.Например, я недавно написал такой запрос, чтобы вычислить изменения между двумя наборами:
-- Let o be the set of old things, and n be the set of new things.
WITH o AS (SELECT * FROM things(OLD)),
n AS (SELECT * FROM things(NEW))
-- Select both the set of things whose value changed,
-- and the set of things in the old set but not in the new set.
SELECT o.key, n.value
FROM o
LEFT JOIN n ON o.key = n.key
WHERE o.value IS DISTINCT FROM n.value
UNION ALL
-- Select the set of things in the new set but not in the old set.
SELECT n.key, n.value
FROM o
RIGHT JOIN n ON o.key = n.key
WHERE o.key IS NULL;
Определив «таблицы» o
и n
вверху, я смог избежать повторениявыражения things(OLD)
и things(NEW)
.
Конечно, мы могли бы, вероятно, исключить UNION ALL
, используя FULL JOIN
, но я не смог этого сделать в моем конкретном случае.
Если я правильно понимаю ваш запрос, он делает это:
Найдите самую старую строку в global.prospect со статусом «новый» или «сброс».
Отметьте его, добавив к его статусу звездочку
Верните строку (включая наш твик в status
).
Не думаю, что WITH
что-нибудь упростит в вашем случае.Может быть немного элегантнее использовать предложение FROM
, хотя:
update global.prospect psp
set status = status || '*'
from ( select psp_id
from global.prospect
where status = 'new' or status = 'reset'
order by request_ts
limit 1
) p2
where psp.psp_id = p2.psp_id
returning psp.*;
Не проверено.Дайте мне знать, если это работает.
Это в значительной степени именно то, что у вас уже есть, за исключением:
Это может быть легко расширено для обновления нескольких строк.В вашей версии, в которой используется выражение подзапроса, запрос не будет выполнен, если подзапрос был изменен для получения нескольких строк.
Я не псевдоним global.prospect
в подзапросе, так что этонемного легче читать.Поскольку при этом используется предложение FROM
, вы получите сообщение об ошибке, если случайно упомянете обновляемую таблицу.
В вашей версии выражение подзапроса встречается для каждого отдельного элемента.Хотя PostgreSQL должен оптимизировать это и оценивать выражение только один раз, эта оптимизация исчезнет, если вы случайно ссылаетесь на столбец в psp
или добавляете переменное выражение.