当前位置: 首页 > 知识库问答 >
问题:

Postgres 9.5+:UPSERT返回更新和插入的行数

黄博艺
2023-03-14
 INSERT INTO user_logins (username, logins)
 VALUES ('Naomi',1),('James',1)
 ON CONFLICT (username)
 DO UPDATE SET logins = user_logins.logins + EXCLUDED.logins;

但现在我也需要知道:

  1. 插入了多少行
  2. 由于现有
  3. 而更新了多少行
  4. 由于约束无法插入多少行
  5. 如果最后一行没有遵守约束,那么以前插入/更新的行是否会保留在数据库中?

共有1个答案

孟永望
2023-03-14

我不知道你怎么能理解发生了什么事。您应该查看xmax的值,如果xmax=0表示there row被插入,其他值xmax there row是update。

我英语不好,我会试着展示这个例子。

create table test3(r1 text unique, r2 text);
\d+ test3
                       Table "public.test3"
 Column | Type | Modifiers | Storage  | Stats target | Description 
--------+------+-----------+----------+--------------+-------------
 r1     | text |           | extended |              | 
 r2     | text |           | extended |              | 
Indexes:
    "test3_r1_key" UNIQUE CONSTRAINT, btree (r1)

插入

INSERT INTO test3 
VALUES('www7','rrr'), ('www8','rrr2') 
ON CONFLICT (r1) DO UPDATE SET r2 = 'QQQQ' RETURNING xmax;
 xmax 
------
    0
    0
INSERT INTO test3 
VALUES('www7','rrr'), ('www8','rrr2') 
ON CONFLICT (r1) DO UPDATE SET r2 = 'QQQQ' RETURNING xmax;
   xmax    
-----------
 430343538
 430343538
(2 rows)

INSERT 0 2
WITH t AS  (
  INSERT INTO test3 
  VALUES('www9','rrr'), ('www7','rrr2') 
  ON CONFLICT (r1) DO UPDATE SET r2 = 'QQQQ' RETURNING xmax
) 
SELECT COUNT(*) AS all_rows, 
       SUM(CASE WHEN xmax = 0 THEN 1 ELSE 0 END) AS ins, 
       SUM(CASE WHEN xmax::text::int > 0 THEN 1 ELSE 0 END) AS upd 
FROM t;

all_rows  | ins | upd 
----------+-----+-----
        2 |   1 |   1
 类似资料:
  • 和都属于类型或任何其他数字数据类型。是我的PK。 现在,我希望在表中执行更新查询,如果该行不存在,我希望插入该行。如果用户已经存在,我希望将点数增加1,否则插入用户ID,点数默认为1。 我知道我可以这样做: 但是,在我的情况下,更新操作比插入新行更频繁。假设每天有5000个查询,其中大约4500行是对现有行的操作。做相反的upsert将是更有利的,因为冲突将减少到500次,而不是4500次。我想先

  • 问题内容: MySQL有这样的东西: 据我所知,SQLite中不存在此功能,我想知道的是,是否有任何方法可以实现相同的效果而不必执行两个查询。另外,如果这不可能,那么您更喜欢什么: SELECT +(插入或更新) 或 UPDATE( 如果UPDATE失败,则 + INSERT ) 问题答案: 因为3.24.0 SQLite还支持upsert ,所以现在您可以简单地编写以下内容

  • 问题内容: 我有这样的UPSERT操作: 是一个复合主键,与“ people”表相比,“ people_update”表包含其他行和已更改的行。 我的问题是:有没有办法将查询的插入行和更新行作为返回行? 编辑:我通过添加一个子句中途解决了问题,但我也想在我的返回值中获取旧值。 问题答案: 如果将布尔更新的列添加到表中: 那么您可以通过在子句中进行设置来标识更新的行: 例如, 产量 该列显示和行已更

  • 好的,这个问题不是关于如何返回ID,而是更像是如何跳过它...我有一种情况,我使用last_insert_id()获取最后插入的行的id,但如果没有插入行,我希望得到一个零。问题如下: I INSERT...UPDATE一些记录:由于行是新插入的,因此返回所有ID 然后重复这个过程:这一次不返回ID。耶!这正是我想要的 我更改了一个列值并重复该过程:但现在返回了我更改了列值的行的ID。这让我很生气

  • 问题内容: 在Slick 3.0中执行批量insertOrUpdate的正确方法是什么? 我正在使用适当的查询的MySQL MySQL批量插入或更新 这是我当前的代码,它很慢:-( 我正在寻找的是等价的 问题答案: 您可以通过多种方法使此代码更快(每个代码都 应该 比前面的代码更快,但是它的习惯用法越来越少): 运行而不是if on slick-pg 0.16.1+ 一次运行所有DBIO事件,而不

  • 问题内容: UPSERT操作会更新表或在表中插入一行,这取决于表是否已经有与数据匹配的行: 由于Oracle没有特定的UPSERT语句,执行此操作的最佳方法是什么? 问题答案: MERGE(“老式方式”)的替代方法: