Sql Upsert查询不使用空值。如何在约束中使用空值进行更新?

Sql Upsert查询不使用空值。如何在约束中使用空值进行更新?,sql,postgresql,upsert,Sql,Postgresql,Upsert,我使用pgsql upsert查询基于三列组合的冲突。这里一列可以为null,也可以不为null,另外两列将始终包含该值。Upsert查询工作(更新值)当所有三列都有值时,如果另一个可以为null的列没有值,则它将插入记录而不是更新 CREATE TABLE "public"."plan_line_items" ( "plan_id" int4 NOT NULL "module_id" int4 NOT NULL, "sub_module_id" int4, "c

我使用pgsql upsert查询基于三列组合的冲突。这里一列可以为null,也可以不为null,另外两列将始终包含该值。Upsert查询工作(更新值)当所有三列都有值时,如果另一个可以为null的列没有值,则它将插入记录而不是更新

CREATE TABLE "public"."plan_line_items" (
    "plan_id" int4 NOT NULL
    "module_id" int4 NOT NULL,
    "sub_module_id" int4,
    "created_date" timestamptz(6) NOT NULL DEFAULT now(),
    "modified_date" timestamptz(6) NOT NULL DEFAULT now(),
    "created_by" int4 NOT NULL,
    "modified_by" int4 NOT NULL,
    "is_active" bool NOT NULL DEFAULT true,
);

INSERT INTO plan_line_items1 ( plan_id,module_id, sub_module_id, created_by, modified_by, modified_date )
VALUES ( '1', '1', '1', '36', '36', 'now()' ),
( '1', '2', null, '36', '36', 'now()' ) ON CONFLICT ( 
plan_id,module_id,sub_module_id ) DO UPDATE SET modified_by = EXCLUDED.modified_by,
modified_date = EXCLUDED.modified_date
当我第一次尝试这个查询时,它正在插入记录。之后,当我第二次尝试时,它只更新所有计划id、模块id、子模块id均为1的记录。不更新已插入第三个空值('1','2',null','36','36','now()')的记录。我尝试了很多方法,但没有找到任何方法。我想在第二次执行此查询而不是插入时更新该记录。
如果有人有解决方案,请提供帮助。

在您的唯一约束的上下文中,您在某种程度上误解了
NULL
的含义(我假设您已经设置了该约束,即使它不在DDL中)

sub\u module\u id
带有
NULL
值并不意味着“此
计划行项目
没有
sub\u module\u id
”,它意味着“我们不知道此
计划行项目
是否有
sub\u module\u id
”。这就是为什么它在您的唯一约束中无法按预期工作的原因

我建议将
子模块id
列的数据类型更改为:

sub_module_id int4 not null default 0
…然后为那些没有
子模块id的
行项目
插入
0
值,而不是
NULL
。因此:

CREATE TABLE regt.plan_line_items (
    plan_id int4 NOT null,
    module_id int4 NOT NULL,
    sub_module_id int4 not null default 0,
    created_date timestamptz(6) NOT NULL DEFAULT now(),
    modified_date timestamptz(6) NOT NULL DEFAULT now(),
    created_by int4 NOT NULL,
    modified_by int4 NOT NULL,
    is_active bool NOT NULL DEFAULT true,
    unique (plan_id,module_id,sub_module_id)
);

INSERT INTO regt.plan_line_items ( plan_id,module_id, sub_module_id, created_by, modified_by, modified_date )
VALUES ( '1', '1', '1', '36', '36', 'now()' ),
( '1', '2', '0', '36', '36', 'now()' ) ON CONFLICT ( 
plan_id,module_id,sub_module_id ) DO UPDATE SET modified_by = EXCLUDED.modified_by,
modified_date = EXCLUDED.modified_date;

或者,换一种说法:
NULL
!=
NULL

好的,谢谢你的帮助Tom,我们可以用这种方式,但我已经根据子模块id是否为NULL做了其他事情。如果我使用这种方式,那么我将不得不根据子模块id是否为空来更改我所做的事情。还有其他方法可以做到这一点吗?
NULL
不是真的(但也不是假的)。