在 postgres 中使用参数时忽略 Null 输入值

Ignoring Null input value when using a parameter with postgres

鉴于这个简单 table fiddle

 CREATE TABLE tbl (
  tbl_id             serial PRIMARY KEY,
  column_a       text NOT NULL,
  isactive bool NOT NULL
);
INSERT INTO tbl VALUES
  (1, 'a', true)
, (2, 'b', true)
, (3, 'c', false);

我看到用户使用此 case 语句来抑制参数

SELECT
tbl_id,
column_a,
isactive
FROM tbl
WHERE CASE WHEN  IS NOT NULL THEN isactive =  ELSE 1=1 end AND
CASE WHEN  IS NOT NULL THEN column_a =  ELSE 1=1 end

我会建议他们使用这种语法

SELECT
tbl_id,
column_a,
isactive
FROM tbl
WHERE ( IS NULL OR isactive = ) and 
( IS NULL OR column_a = )

我认为这些是等价的(而且可能更容易阅读)。你会做些不同的事情吗?

你的建议肯定比CASE声明更好,而且效率不低。

但是OR通常是WHERE条件下的问题,因为这使得PostgreSQL很难使用索引来加速查询。

更好的解决方案是:

  • 仅当参数IS NOT NULL

    时才在查询中添加WHERE条件
  • 将查询写成 UNION:

      SELECT tbl_id, column_a, isactive
      FROM tbl
      WHERE isactive =  AND column_a = 
    UNION ALL
      SELECT tbl_id, column_a, isactive
      FROM tbl
      WHERE isactive =  AND  IS NULL
    UNION ALL
      SELECT tbl_id, column_a, isactive
      FROM tbl
      WHERE  IS NULL AND column_a = 
    UNION ALL
      SELECT tbl_id, column_a, isactive
      FROM tbl
      WHERE  IS NULL AND  IS NULL;
    

    看起来更长更复杂,但是它可以在isactivecolumn_a上使用索引。