Рассматривали ли вы использование CTE ?
Например, предположим, что у нас есть следующая таблица
CREATE TABLE test_table (
id BIGINT PRIMARY KEY,
some_data INTEGER
);
Допустим, мы хотимудалить все строки, в которых результат выражения
some_data% 10
равен (> = 1 и <= 4) или (> = 6 и <= 8).</p>
В этом случае операция по модулю заменяет ваш foo(bar(baz(column_name)))
вызов операцией по модулю.
Простой подход заключается в написании следующего запроса:
DELETE FROM test_table
WHERE
(MOD(some_data, 10) >= 1 AND MOD(some_data, 10) <= 4)
OR
(MOD(some_data, 10) >=6 AND MOD(some_data, 10) <= 8);
AsВы сказали, что это будет пересчитывать одно и то же несколько раз.Чтобы выполнить вычисление только один раз, мы можем создать CTE
и использовать результат в запросе на удаление.
WITH precalculated_table AS (
SELECT *, mod(some_data, 10) as mod_10_result FROM test_table
)
DELETE FROM test_table WHERE id IN (
SELECT id from precalculated_table
where
(mod_10_result >= 1 and mod_10_result <= 4)
OR
(mod_10_result >= 6 AND mod_10_result <= 8)
);
Таким образом, мы выполняем вычисление только один раз, а затем используем предварительно вычисленный столбец.в WHERE
части запроса DELETE
.