我需要创建一个带有可选参数的过程,并且只有在它们不为空时才使用它们
我当前的查询如下:
SELECT * FROM sth WHERE
(arg1 IS NULL OR sth.c1 = arg1) AND
(arg2 IS NULL OR sth.c2 = arg2) AND
(arg3 IS NULL OR sth.c3 > arg3) AND
(arg4 IS NULL OR sth.c4 < arg4)
我正在考虑一种让它看起来更好/更短的方法。我的第一枪是:
SELECT * FROM sth WHERE
COALESCE(sth.c1 = arg1, 't') AND
COALESCE(sth.c2 = arg2, 't') AND
COALESCE(sth.c3 > arg3, 't') AND
COALESCE(sth.c4 < arg4, 't');
但我不确定这看起来是否更好。你知道任何有用的技巧吗?
答案 0 :(得分:3)
保持原样。使用coalesce将阻止查询计划程序正确地执行其工作,并且您将最终得到糟糕的查询计划。
最好我知道,以下表达式将使用btree索引:
col = 'val'
col is null
以下表达式不会使用btree索引:
col is [not] 'val'
(col = 'val') is [not] <true | false | null>
col is [not] distinct from 'val'
coalesce(col, 'val') = 'val'
coalesce(col = 'val', <true | false | null>)
答案 1 :(得分:1)
好的,我认为这个查询最适合这个目的
SELECT * FROM sth WHERE
NOT (sth.c1 = arg1) IS FALSE AND
NOT (sth.c2 = arg2) IS FALSE AND
NOT (sth.c3 > arg3) IS FALSE AND
NOT (sth.c4 < arg4) IS FALSE;
它不使用任何函数,因此查询计划器应该正常工作
它只使用简单的表达式:
1.
true = true // true
true = false // false
true = null // null
2.
false is false // true
true is false // false
null is false // false
3.
not true // false
not false // true
如果表达式为true
或true
null