Есть несколько техник, но есть кое-что, о чем нужно знать; Попытка сжать два типа функциональности в одном запросе часто приводит к плохим планам выполнения. (Например, сканирование таблицы или индекса, а не поиск индекса).
Мне часто бывает лучше переосмыслить структуру данных и / или переосмыслить, как формировать запрос.
Отвечая на конкретный пример в вашем вопросе, я бы сделал это ...
WHERE
CASE WHEN VALUE < X THEN 1
WHEN VALUE = X THEN 2
WHEN VALUE > X THEN 4
END
|
CASE ValueLowerLimitOperator
WHEN '<' THEN 1
WHEN '<=' THEN 3
WHEN '=' THEN 2
WHEN '>=' THEN 6
WHEN '>' THEN 4
END
<>
0
Однако, безусловно, не будут использованы какие-либо индексы.
Другой вариант - просто кодировать каждый сценарий ...
WHERE
CASE ValueLowerLimitOperator
WHEN '<' THEN CASE WHEN VALUE < X THEN 1 ELSE 0 END
WHEN '<=' THEN CASE WHEN VALUE <= X THEN 1 ELSE 0 END
WHEN '=' THEN CASE WHEN VALUE = X THEN 1 ELSE 0 END
WHEN '>=' THEN CASE WHEN VALUE >= X THEN 1 ELSE 0 END
WHEN '>' THEN CASE WHEN VALUE > X THEN 1 ELSE 0 END
END
=
1
Или, возможно, несколько объединенных запросов
WITH main_query AS (SELECT * FROM blah)
SELECT * FROM main_query WHERE ValueLowerLimitOperator = '<' AND VALUE < X
UNION ALL
SELECT * FROM main_query WHERE ValueLowerLimitOperator = '<=' AND VALUE <= X
UNION ALL
SELECT * FROM main_query WHERE ValueLowerLimitOperator = '=' AND VALUE = X
UNION ALL
SELECT * FROM main_query WHERE ValueLowerLimitOperator = '>=' AND VALUE >= X
UNION ALL
SELECT * FROM main_query WHERE ValueLowerLimitOperator = '>' AND VALUE > X
Может быть, даже использовать функцию для декодирования всего этого?
SELECT
*
FROM
main_query
CROSS APPLY
dbo.my_function(ValueLowerLimitOperator, VALUE, X) AS check
WHERE
check.return_value = 1
(Using CROSS APPLY with a Inline Table Valued Function will be MUCH faster than a Scalar Function in the WHERE clause)
Когда вы выглядите так, как будто вы хотите, чтобы это повторилось для LowerLimit, UpperLimit и т. Д., Инкапсуляция этого в функцию кажется хорошей идеей для меня.