PostgreSQL:从跨列比较中排除空值

Joe*_*hat 0 sql postgresql null boolean-logic case

想象一下这张表:

id   col1    col2    col3    col4
1    A       A       C
2            B       B       B
3    D               D
Run Code Online (Sandbox Code Playgroud)

我想添加一列来告诉我该行的所有非空值是否匹配。

所以理想的输出是:

id   col1    col2    col3    col4   is_a_match
1    A       A       C              FALSE
2            B       B       B      TRUE
3    D               D              TRUE
Run Code Online (Sandbox Code Playgroud)

我努力了:

select *,
     case  
         when col1 = col2
                and col2 = col3
                and col3 = col4
         then 'TRUE'
         else 'FALSE'
     end as is_a_match
from my_table
Run Code Online (Sandbox Code Playgroud)

false但由于空值,将返回所有内容。

实现上述输出的最佳方法是什么?

小智 6

您可以将列转换为行,对不同值进行计数。这将自动忽略 NULL 值:

select t.*,
       (select count(distinct x.col)
        from (
          values (t.col1), 
                 (t.col2), 
                 (t.col3), 
                 (t.col4)
        ) as x(col)
        where x.col is not null) = 1 as is_a_match
from the_table t
Run Code Online (Sandbox Code Playgroud)

如果您不想手动列出所有列,可以使用一些 JSON 魔法将列转换为行,以便计算不同的值:

select t.*, 
       (select count(distinct x.val)
        from jsonb_each_text(to_jsonb(t) - 'id') as x(col, val)
        where x.val is not null) = 1
from the_table t
Run Code Online (Sandbox Code Playgroud)