Sql 如果要比较的列中可能存在空/空值,是否始终需要在WHERE中使用coalesce?

Sql 如果要比较的列中可能存在空/空值,是否始终需要在WHERE中使用coalesce?,sql,database,postgresql,Sql,Database,Postgresql,我知道不能将空/空的列与其他列进行比较,所以我经常会编写如下查询: WHERE field2 <> '' AND coalesce(field1, '') <> coalesce(field2, '') 我一直都是这样做的,但我很好奇是否有更好的方法来处理空值。我也很好奇为什么要这么做。不。使用合并通常会阻止索引的使用。使用布尔逻辑的等效语法变得很麻烦 最好的解决方案是使用不同于: 通过使用内置操作符,Postgres可以更好地优化查询。不同于。号中解释的ANSI标准语

我知道不能将空/空的列与其他列进行比较,所以我经常会编写如下查询:

WHERE field2 <> '' AND coalesce(field1, '') <> coalesce(field2, '')
我一直都是这样做的,但我很好奇是否有更好的方法来处理空值。我也很好奇为什么要这么做。

不。使用合并通常会阻止索引的使用。使用布尔逻辑的等效语法变得很麻烦

最好的解决方案是使用不同于:

通过使用内置操作符,Postgres可以更好地优化查询。不同于。

号中解释的ANSI标准语法。使用合并通常会阻止使用索引。使用布尔逻辑的等效语法变得很麻烦

最好的解决方案是使用不同于:


通过使用内置操作符,Postgres可以更好地优化查询。与ANSI标准语法不同的是。

一个小注释中解释的ANSI标准语法:COALESCEt1.val、COALESCEt2.val和t1.val的结果与t2.val不同,因为NULL是NULL。真值表示例:

CREATE TABLE three
        ( id serial not null primary key
        , val text
        );
insert into three(val) VALUES(NULL), ('') , ('a') , ('b' );



SELECT COALESCE(t1.val, '<NULL>' ) AS t1val     -- <NULL> for readability
        ,COALESCE(t2.val, '<NULL>' ) AS t2val   -- <NULL> for readability
        , (t1.val <> t2.val) AS is_ne
        , (COALESCE(t1.val, '') <> COALESCE(t2.val, '')) AS coa_is_ne
        , (t1.val IS DISTINCT FROM t2.val) AS is_distinct
FROM three t1, three t2
ORDER BY t1.val,t2.val
        ;
 t1val  | t2val  | is_ne | coa_is_ne | is_distinct 
--------+--------+-------+-----------+-------------
        |        | f     | f         | f
        | a      | t     | t         | t
        | b      | t     | t         | t
        | <NULL> |       | f         | t          # <<-- here
 a      |        | t     | t         | t
 a      | a      | f     | f         | f
 a      | b      | t     | t         | t
 a      | <NULL> |       | t         | t
 b      |        | t     | t         | t
 b      | a      | t     | t         | t
 b      | b      | f     | f         | f
 b      | <NULL> |       | t         | t
 <NULL> |        |       | f         | t          # <<-- and here
 <NULL> | a      |       | t         | t
 <NULL> | b      |       | t         | t
 <NULL> | <NULL> |       | f         | f
(16 rows)
结果真值表:

CREATE TABLE three
        ( id serial not null primary key
        , val text
        );
insert into three(val) VALUES(NULL), ('') , ('a') , ('b' );



SELECT COALESCE(t1.val, '<NULL>' ) AS t1val     -- <NULL> for readability
        ,COALESCE(t2.val, '<NULL>' ) AS t2val   -- <NULL> for readability
        , (t1.val <> t2.val) AS is_ne
        , (COALESCE(t1.val, '') <> COALESCE(t2.val, '')) AS coa_is_ne
        , (t1.val IS DISTINCT FROM t2.val) AS is_distinct
FROM three t1, three t2
ORDER BY t1.val,t2.val
        ;
 t1val  | t2val  | is_ne | coa_is_ne | is_distinct 
--------+--------+-------+-----------+-------------
        |        | f     | f         | f
        | a      | t     | t         | t
        | b      | t     | t         | t
        | <NULL> |       | f         | t          # <<-- here
 a      |        | t     | t         | t
 a      | a      | f     | f         | f
 a      | b      | t     | t         | t
 a      | <NULL> |       | t         | t
 b      |        | t     | t         | t
 b      | a      | t     | t         | t
 b      | b      | f     | f         | f
 b      | <NULL> |       | t         | t
 <NULL> |        |       | f         | t          # <<-- and here
 <NULL> | a      |       | t         | t
 <NULL> | b      |       | t         | t
 <NULL> | <NULL> |       | f         | f
(16 rows)

一个小提示:COALESCEt1.val、COALESCEt2.val和t1.val的结果与t2.val不同,因为NULL是NULL。真值表示例:

CREATE TABLE three
        ( id serial not null primary key
        , val text
        );
insert into three(val) VALUES(NULL), ('') , ('a') , ('b' );



SELECT COALESCE(t1.val, '<NULL>' ) AS t1val     -- <NULL> for readability
        ,COALESCE(t2.val, '<NULL>' ) AS t2val   -- <NULL> for readability
        , (t1.val <> t2.val) AS is_ne
        , (COALESCE(t1.val, '') <> COALESCE(t2.val, '')) AS coa_is_ne
        , (t1.val IS DISTINCT FROM t2.val) AS is_distinct
FROM three t1, three t2
ORDER BY t1.val,t2.val
        ;
 t1val  | t2val  | is_ne | coa_is_ne | is_distinct 
--------+--------+-------+-----------+-------------
        |        | f     | f         | f
        | a      | t     | t         | t
        | b      | t     | t         | t
        | <NULL> |       | f         | t          # <<-- here
 a      |        | t     | t         | t
 a      | a      | f     | f         | f
 a      | b      | t     | t         | t
 a      | <NULL> |       | t         | t
 b      |        | t     | t         | t
 b      | a      | t     | t         | t
 b      | b      | f     | f         | f
 b      | <NULL> |       | t         | t
 <NULL> |        |       | f         | t          # <<-- and here
 <NULL> | a      |       | t         | t
 <NULL> | b      |       | t         | t
 <NULL> | <NULL> |       | f         | f
(16 rows)
结果真值表:

CREATE TABLE three
        ( id serial not null primary key
        , val text
        );
insert into three(val) VALUES(NULL), ('') , ('a') , ('b' );



SELECT COALESCE(t1.val, '<NULL>' ) AS t1val     -- <NULL> for readability
        ,COALESCE(t2.val, '<NULL>' ) AS t2val   -- <NULL> for readability
        , (t1.val <> t2.val) AS is_ne
        , (COALESCE(t1.val, '') <> COALESCE(t2.val, '')) AS coa_is_ne
        , (t1.val IS DISTINCT FROM t2.val) AS is_distinct
FROM three t1, three t2
ORDER BY t1.val,t2.val
        ;
 t1val  | t2val  | is_ne | coa_is_ne | is_distinct 
--------+--------+-------+-----------+-------------
        |        | f     | f         | f
        | a      | t     | t         | t
        | b      | t     | t         | t
        | <NULL> |       | f         | t          # <<-- here
 a      |        | t     | t         | t
 a      | a      | f     | f         | f
 a      | b      | t     | t         | t
 a      | <NULL> |       | t         | t
 b      |        | t     | t         | t
 b      | a      | t     | t         | t
 b      | b      | f     | f         | f
 b      | <NULL> |       | t         | t
 <NULL> |        |       | f         | t          # <<-- and here
 <NULL> | a      |       | t         | t
 <NULL> | b      |       | t         | t
 <NULL> | <NULL> |       | f         | f
(16 rows)

field2和field1与field2不同的地方是postgres ExtensionCalese,它通过确保比较值(而不是值与非值)使操作变得简单。至于为什么使用3VL,请参阅和了解一些背景信息。其中field2和field1与field2不同,field2和field1不同于是postgres ExtensionCalese通过确保比较值(而不是值与非值)使操作变得简单。至于为什么使用3VL,请参阅和了解一些背景信息。为什么合并会阻止使用索引?@AR7。在几乎任何数据库中,列上的几乎任何函数都禁止使用索引。这里也有例外,但一般来说,函数会阻止使用索引。为什么合并会阻止使用索引?@AR7。在几乎任何数据库中,列上的几乎任何函数都禁止使用索引。这里也有例外,但一般来说,函数会阻止使用索引。