Используйте предложение FROM
для команды UPDATE
:
UPDATE etl_telco_cycle e
SET amount_mobilephone_numbers = c.ct
FROM (
SELECT e.customer_number, count(distinct document_key) AS ct
FROM telco_document_header t
JOIN etl_telco_cycle e ON t.customer_number like '%' || e.customer_number
WHERE t.document_cycle = substring(cast(now() - interval '1 month' as varchar) from 1 for 4)
|| substring(cast(now() - interval '1 month' as varchar) from 6 for 2)
GROUP BY 1
) c
WHERE e.customer_number = c.customer_number
AND e.amount_mobilephone_numbers IS DISTINCT FROM c.ct; --optional optimization
Несмотря на то, что вы также можете использовать коррелированный подзапрос, он, как правило, будет намного медленнее, запуская один запрос агрегации на целевую строку, в то время как этот запрос запускает одиночный запрос агрегации. И есть небольшая разница: если в коррелированном подзапросе, например, не найдено связанных строк, например, * Гордон показывает , столбец по-прежнему обновляется до NULL (что не удалось бы для столбцов, определенных NOT NULL
), в то время как мой запрос делает ничего вместо этого (сохраняя старое значение). Вам нужно определить желаемое поведение.
Добавленный AND e.amount_mobilephone_numbers IS DISTINCT FROM c.ct
предотвращает пустые обновления. Связанный:
Вы можете еще больше оптимизировать производительность подзапроса. Вам может не потребоваться DISTINCT
или JOIN
в подзапросе - вам нужно будет увидеть точные определения и ограничения таблицы. Похоже, вы можете заменить это в любом случае:
substring(cast(now() - interval '1 month' as varchar) from 1 for 4)
|| substring(cast(now() - interval '1 month' as varchar) from 6 for 2)
с:
to_char(now() - interval '1 month', 'YYYYMM')
Либо зависит от текущей настройки timezone
, что может быть нежелательно в угловых случаях.
И document_cycle
должны быть date
или integer
, а не строковым типом ...