在冲突上如何努力两个或多个约束?

发布于 2025-01-24 15:29:43 字数 756 浏览 3 评论 0原文

我有一个表:

“在此处输入图像描述”

我想从另一个表中获取插入或更新数据。我的约束是三个字段:ID_1,ID_2和日期。它的字段必须在一起是唯一的。 如果我这样做:

ALTER TABLE my_table
ADD CONSTRAINT constr_1 UNIQUE (id_1, id_2, date);

然后:

insert into my_table
(id_1, id_2, quantity, date)
values (1, null, 5, '2022-04-27'),   -- values I get another select request
       (null, 5, 5, '2022-04-27'),  -- this means that the values can be different
       (99, 85, 100, '2022-04-29')
ON CONFLICT (id_1, id_2, date)
DO Update
SET quantity = excluded.quantity

约束不起作用,我只是插入具有相同值的新行。如何在没有记录和更新的情况下插入?

I have a table:

enter image description here

I want insert or update data, that I get from another table. My constrains are three fields: id_1, id_2 and date. It's fields must be unique together.
If I do:

ALTER TABLE my_table
ADD CONSTRAINT constr_1 UNIQUE (id_1, id_2, date);

and then:

insert into my_table
(id_1, id_2, quantity, date)
values (1, null, 5, '2022-04-27'),   -- values I get another select request
       (null, 5, 5, '2022-04-27'),  -- this means that the values can be different
       (99, 85, 100, '2022-04-29')
ON CONFLICT (id_1, id_2, date)
DO Update
SET quantity = excluded.quantity

Constrains not work and I just insert new rows with the same values. How to insert in the absence of a record and update in its presence?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

往日 2025-01-31 15:29:43

PostgreSQL将零视为独特的值,因此,您可以在具有唯一索引的列中具有多个空值。当您为表定义主键或唯一约束时,PostgreSQL会自动创建相应的唯一索引。
解决方案是与Colesce创建一个独特的索引。在此示例中,我使用了cocce(〜,0),这意味着Null和0被视为同一件事。您可能更喜欢使用另一个值,例如int的最大可能值,即2147483648。请不要修改冲突列表以匹配索引。

 创建temp表my_table(
    id_1 int,
    id_2 int,
    数量数字,
    mytable_date日期
);
 
 创建唯一的索引
my_table_unique my_table
(cocce(id_1,0),cocece(id_2,0),cocece(mytable_date,'1900-01-01'));
 
 插入my_table(ID_1,ID_2,数量,mytable_date)
    值(1,Null,5,'2022-04-27'),(Null,5,5,'2022-04-27'),(99,85,100,'2022-04-29')
关于冲突(Cocce(ID_1,0),CoceCe(ID_2,0),Cocece(Mytable_date,'1900-01-01'))
    做更新集
        数量=排除。

插入my_table(ID_1,ID_2,数量,mytable_date)
    值(99、85、101,'2022-04-29')
关于冲突(Cocce(ID_1,0),CoceCe(ID_2,0),Cocece(Mytable_date,'1900-01-01'))
    做更新集
        数量=排除。
 
 

3行影响

1行影响

 从my_table中选择 *;
 
 id_1 | ID_2 |数量| mytable_date
---:| ---:| -------:| :-----------------
   1 |  null  | 5 | 2022-04-27  
 null  | 5 | 5 | 2022-04-27  
  99 | 85 | 101 | 2022-04-29  

*db< EC5F)

PostgreSQL treats NULL as distinct value, therefore, you can have multiple NULL values in a column with a UNIQUE index. When you define a primary key or a unique constraint for a table, PostgreSQL automatically creates a corresponding UNIQUE index.
The solution is to create a unique index, with coalesce. In this example I have used coalesce(~, 0) which means that null and 0 are treated as the same thing. You might prefer to use another value, for example the maximum possible value of int which is 2147483648.Please not that we have to modify the ON CONFLICT list to match the index.

CREATE temp TABLE my_table (
    id_1 int,
    id_2 int,
    quantity numeric,
    mytable_date date
);
CREATE UNIQUE INDEX
my_table_unique ON my_table
(coalesce(id_1,0), coalesce(id_2,0), coalesce(mytable_date,'1900-01-01'));
INSERT INTO my_table (id_1, id_2, quantity, mytable_date)
    VALUES (1, NULL, 5, '2022-04-27'), (NULL, 5, 5, '2022-04-27'), (99, 85, 100, '2022-04-29')
ON CONFLICT (coalesce(id_1,0), coalesce(id_2,0), coalesce(mytable_date,'1900-01-01'))
    DO UPDATE SET
        quantity = excluded.quantity;

INSERT INTO my_table (id_1, id_2, quantity, mytable_date)
    VALUES (99, 85, 101, '2022-04-29')
ON CONFLICT (coalesce(id_1,0), coalesce(id_2,0), coalesce(mytable_date,'1900-01-01'))
    DO UPDATE SET
        quantity = excluded.quantity;

3 rows affected

1 rows affected

select * from my_table;
id_1 | id_2 | quantity | mytable_date
---: | ---: | -------: | :-----------
   1 | null |        5 | 2022-04-27  
null |    5 |        5 | 2022-04-27  
  99 |   85 |      101 | 2022-04-29  

*db<>fiddle here74bf159a4d041c31fec5f)

花桑 2025-01-31 15:29:43
CREATE temp TABLE my_table (
    id_1 int,
    id_2 int,
    quantity numeric,
    mytable_date date
);

ALTER TABLE my_table
    ADD CONSTRAINT constr_1 UNIQUE (id_1, id_2, mytable_date);

然后,

INSERT INTO my_table (id_1, id_2, quantity, mytable_date)
    VALUES (1, NULL, 5, '2022-04-27'), (NULL, 5, 5, '2022-04-27'), (99, 85, 100, '2022-04-29')
ON CONFLICT (id_1, id_2, mytable_date)
    DO UPDATE SET
        quantity = excluded.quantity;

INSERT INTO my_table (id_1, id_2, quantity, mytable_date)
    VALUES (99, 85, 101, '2022-04-29')
ON CONFLICT (id_1, id_2, mytable_date)
    DO UPDATE SET
        quantity = excluded.quantity;

请检查手册部分: 5.4.3。独特的约束关于特殊情况: null

通常,如果有多个
表中的行,所有包含的所有列的值
约束是相等的。但是,两个无效的值永远不会
在此比较中被认为是平等的。
即使在存在
一个独特的约束,可以存储重复行
在至少一个约束列中包含一个空值。这
行为符合SQL标准,但我们听说过其他
SQL数据库可能不遵循此规则。因此,请小心
旨在便携的开发应用程序。

CREATE temp TABLE my_table (
    id_1 int,
    id_2 int,
    quantity numeric,
    mytable_date date
);

ALTER TABLE my_table
    ADD CONSTRAINT constr_1 UNIQUE (id_1, id_2, mytable_date);

then

INSERT INTO my_table (id_1, id_2, quantity, mytable_date)
    VALUES (1, NULL, 5, '2022-04-27'), (NULL, 5, 5, '2022-04-27'), (99, 85, 100, '2022-04-29')
ON CONFLICT (id_1, id_2, mytable_date)
    DO UPDATE SET
        quantity = excluded.quantity;

INSERT INTO my_table (id_1, id_2, quantity, mytable_date)
    VALUES (99, 85, 101, '2022-04-29')
ON CONFLICT (id_1, id_2, mytable_date)
    DO UPDATE SET
        quantity = excluded.quantity;

please check manual section: 5.4.3. Unique Constraints about special case: null.

In general, a unique constraint is violated if there is more than one
row in the table where the values of all of the columns included in
the constraint are equal. However, two null values are never
considered equal in this comparison.
That means even in the presence
of a unique constraint it is possible to store duplicate rows that
contain a null value in at least one of the constrained columns. This
behavior conforms to the SQL standard, but we have heard that other
SQL databases might not follow this rule. So be careful when
developing applications that are intended to be portable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文