PostgreSQL:`row_alias is null`和`row_alias is not null`返回值不一致

问题描述 投票:0回答:1

我在 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 不为空 | | :--- | :--- | :--- | :--- | | 1 | ("0000-00-00 00:00:00.000000+00",系统,"0000-00-00 00:00:00.000000+00",系统,0000,正常,00000FEE,f00d0000-0b0b-000a-0e00-0a0e00000b00 ,t,用户名1,用户名2,"用户名1",f,t,f,aad,用户名1,用户名2,,"用户名1 用户名2") |假 |假|

问题在于,

ui is null
ui is not null
列的结果行值都是
false
,而
row_value
列包含本身(不是
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
的相反值。

提前致谢


编辑:

当使用特定字段的语法时(如

ui.user_id is (not) null
),问题就消失了。那么我想问一下这种形式是否是普遍首选,或者我原来的方法也应该有效? (我过去直接检查row没有遇到这样的问题)

postgresql left-join postgresql-15
1个回答
0
投票

参见简短示例

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

输出是

id 瓦尔 is_null is_not_null
1 100 f t
1 f f
© www.soinside.com 2019 - 2024. All rights reserved.