A CASE
выражение может возвращать только одиночное значение (boolean
в моей фиксированной версии), а не условный код, как вы пытались:
SELECT val_1, val_2, val_3
FROM schema_name.table_name
WHERE CASE $1
WHEN 'a' THEN val_3 BETWEEN 0 AND 1
WHEN 'b' THEN val_3 BETWEEN 2 AND 7
.
.
.
WHEN 'g' THEN val_3 BETWEEN 50 AND 100
END;
Использование «простой» формы CASE
, чтобы сделать ее немного короче и быстрее.
В качестве альтернативы, просто используйте логические логики c only:
...
WHERE (
$1 = 'a' AND val_3 BETWEEN 0 AND 1
OR $1 = 'b' AND val_3 BETWEEN 2 AND 7
.
.
.
OR $1 = 'g' AND val_3 BETWEEN 50 AND 100
)
Скобки не нужны строго, так как приоритет оператора в любом случае работает в нашу пользу. AND
связывается до OR
и BETWEEN
связывается до обоих. Но вам понадобятся эти скобки, если вы добавите еще одно WHERE
условие с AND
.
Производительность?
Для обоих вариантов Postgres 12 (не тестировалось для более ранних версий ) достаточно умен, чтобы все еще использовать индекс на (val_3)
или нет, в зависимости от фактической статистики столбца. Даже для подготовленных операторов.
Если эта функция вызывается много,
, и вы работаете с подготовленными операторами (прямо или косвенно),
и производительность критична,
и некоторые из ваших диапазонов извлекают выгоду из индекса, в то время как другие не
, тогда вы все равно могли бы форкать (как минимум) два отдельных запроса для работы с обобщенными c, сохраненными планами запросов в любом случае, чтобы получить абсолютный лучший результат производительность.