在 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;
看起来更长更复杂,但是它可以在isactive
和column_a
上使用索引。
鉴于这个简单 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;
看起来更长更复杂,但是它可以在
isactive
和column_a
上使用索引。