我在SQL select中偶然发现了一个奇怪的现象:

select 1
, ui as row_value
, ui is null as "ui is null"
, ui is not null as "ui is not null"
from user_info ui
where ui.user_id = 1003;

此SQL查询的输出: | ?专栏?| UI| UI为null| UI不为空| | ———|———|———|———| | 1|("0000—00—00 00:00:00.00000 + 00",系统,"0000—00—00 00:00:00.0000000 + 00",系统,0000,正常,00000FEE,f00d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000|虚假|虚假|

问题是ui is nullui is not null列的结果行值都是false,而列row_value包含row本身(不是null).


奇怪的是,我无法设法用内联值来再现它,例如:

-- working as expected
select row(1, 2, 'Hello') as original_row
, row(1, 2, 'Hello') is null as row_is_null
, row(1, 2, 'Hello') is not null as row_is_not_null

甚至不使用虚拟表格:

-- working as expected

create table table_1
(
    table_1_id int not null primary key generated always as identity,
    title      text
);

create table table_2
(
    table_2_id int not null primary key generated always as identity,
    title      text,
    table_1_id int references table_1 on delete cascade
);

create table table_3
(
    table_3_id int not null primary key generated always as identity,
    title      text,
    table_2_id int references table_2 on delete cascade
);

insert into table_1 (title)
values ('Table1 Row 1')
         , ('Table1 Row 2');

insert into table_2 (title, table_1_id)
values ('Table2 Row 1', 1)
         , ('Table2 Row 2', 2);

insert into table_3 (title, table_2_id)
values ('Table3 Row 1', 1)
         , ('Table3 Row 2', 2);

select t1.title
         , t2
         -- , t2 is null
         -- , t2 is not null
         , t3
         , t3 is null
         , t3 is not null
from table_1 t1
    left join public.table_2 t2 using (table_1_id)
    left join public.table_3 t3 on t2.table_2_id = t3.table_2_id and t3.title = 'Table3 Row 1'
where t1.table_1_id = 1
;

这两个最新的代码片段都按预期工作,即x is null返回的值与x is not null相反.

thanks in advance


EDIT:

当使用特定字段的语法时(如ui.user_id is (not) null),那么问题就消失了.那么,我想问一个问题,这是普遍喜欢的形式,还是我原来的方法也应该工作?(我以前没有直接判断row的问题)

推荐答案

Your result is quite consistent with the expected behavior. When you check for the is null tuple condition, you can get the results
is null (1,null) - is false
and
is not null (1,null) - is false.

集合的某些部分为空,其他部分不为空.是null(null,null)—是真的.

参见简短示例

create table test (id int,val int);
insert into test values
 (1,100)
,(2,null)
,(null,null)
;
select id,val
  ,test is null as is_null
  ,test is not null as is_not_null
from test

输出

id val is_null is_not_null
1 100 f t
2 null f f
null null t f

Postgresql相关问答推荐

我无法在过程中提交

使用postgres在go测试容器中使用tern迁移

supabase 中的交易

PL/pgSQL中的IP递增函数

在Postgres中如何连接具有相同名称列的表并更改列名称?

在Go中从Kafka读取并写入PostgreSQL时如何处理错误?

在 postgres/presto/AWS-Athena 中,与 array_agg( (col1, col2) ) 相反的是什么来获得每组多行?

PostgreSQL pg_dump 创建 sql 脚本,但它不是 sql 脚本:有没有办法让 pg_dump 创建标准的 sql 脚本?

如何使用 PostgreSQL 数据库中的函数和存储过程从动态表中获取所有数据?参数传入的表名

如何在postgresql中按时间查询

使用间隔参数的 go postgres 准备好的语句不起作用

全文搜索(Postgres)与Elastic search

postgres 和 python

如何将1 天 01:30:00等间隔转换为25:30:00?

为什么 sqlalchemy 的默认列值不起作用

我怎样才能知道 Postgresql 表空间中有什么?

从 PostgreSQL 序列中 Select 多个 id

用于将布尔列排序为 true、null、false 的 SQL

错误:permission denied for language c

PostgreSQL:如何解决numeric field overflow问题