【问题标题】:MySQL/MariaDB ON DUPLICATE KEY UPDATE based on conditionMySQL/MariaDB ON DUPLICATE KEY UPDATE 基于条件
【发布时间】:2018-03-29 08:43:27
【问题描述】:

我想使用条件

重复密钥更新

根据this question 中提供的示例,假设name 是主键。我们要执行以下查询:

INSERT INTO beautiful (name, age, col3, col 4, ..., col 100)
    VALUES
    ('Helen', 24, ...),
    ('Katrina', 21, ...),
    ('Samia', 22, ...),
    ('Hui Ling', 25, ...),
    ('Yumie', 29, ...)
ON DUPLICATE KEY UPDATE
    age = VALUES(age),
    col3= VALUES(col3),
    col4= VALUES(col4),
     ...
    col100= VALUES(col100)

并且(在 MariaDB 中)我希望更新完成,只有当新收到的记录的年龄大于数据库中已经存在的记录时。

有没有办法做到这一点?

更新:更新以反映每条记录都有多个字段

【问题讨论】:

  • 是的,有触发器

标签: mysql sql mariadb


【解决方案1】:

看似微不足道

MariaDB [sandbox]> create table t(name varchar(20),age int default 0 , primary key(name));
Query OK, 0 rows affected (0.28 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> INSERT INTO t (name, age)
    ->     VALUES
    ->     ('Helen', 24),
    ->     ('Katrina', 21),
    ->     ('Samia', 22),
    ->     ('Hui Ling', 25),
    ->     ('Yumie', 29)
    -> ON DUPLICATE KEY UPDATE
    ->     age = if(VALUES(age) > age,values(age),age);
Query OK, 5 rows affected (0.03 sec)
Records: 5  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+----------+------+
| name     | age  |
+----------+------+
| Helen    |   24 |
| Hui Ling |   25 |
| Katrina  |   21 |
| Samia    |   22 |
| Yumie    |   29 |
+----------+------+
5 rows in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> INSERT INTO t (name, age)
    ->     VALUES
    ->     ('Helen', 25),
    ->     ('Katrina', 21),
    ->     ('Samia', 22),
    ->     ('Hui Ling', 25),
    ->     ('Yumie', 29)
    -> ON DUPLICATE KEY UPDATE
    ->     age = if(VALUES(age) > age,values(age),age);
Query OK, 2 rows affected (0.02 sec)
Records: 5  Duplicates: 1  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+----------+------+
| name     | age  |
+----------+------+
| Helen    |   25 |
| Hui Ling |   25 |
| Katrina  |   21 |
| Samia    |   22 |
| Yumie    |   29 |
+----------+------+
5 rows in set (0.00 sec)

如果有n列在年龄变化时更新,那么

drop table if exists t;

create table t(name varchar(20),age int default 0 , col1 int, col2 int,col3 int,primary key(name));
INSERT INTO t (name, age, col1,col2,col3)
 VALUES
      ('Helen', 24,1,1,1),
      ('Katrina', 21,1,1,1),
      ('Samia', 22,1,1,1),
      ('Hui Ling', 25,1,1,1),
      ('Yumie', 29,1,1,1)
  ON DUPLICATE KEY UPDATE
     col1 = if(VALUES(age) > age,values(col1),col1),
     col2 = if(VALUES(age) > age,values(col2),col2),
     col3 = if(VALUES(age) > age,values(col3),col3),
     age = if(VALUES(age) > age,values(age),age);

select * from t;
INSERT INTO t (name, age, col1,col2,col3)
 VALUES
      ('Helen', 25,2,2,2),
      ('Katrina', 21,2,2,2),
      ('Samia', 22,1,1,1),
      ('Hui Ling', 25,1,1,1),
      ('Yumie', 29,1,1,1)
  ON DUPLICATE KEY UPDATE
      col1 = if(VALUES(age) > age,values(col1),col1),
     col2 = if(VALUES(age) > age,values(col2),col2),
     col3 = if(VALUES(age) > age,values(col3),col3),
     age = if(VALUES(age) > age,values(age),age);

select * from t;

MariaDB [sandbox]> select * from t;
+----------+------+------+------+------+
| name     | age  | col1 | col2 | col3 |
+----------+------+------+------+------+
| Helen    |   25 |    2 |    2 |    2 |
| Hui Ling |   25 |    1 |    1 |    1 |
| Katrina  |   21 |    1 |    1 |    1 |
| Samia    |   22 |    1 |    1 |    1 |
| Yumie    |   29 |    1 |    1 |    1 |
+----------+------+------+------+------+
5 rows in set (0.00 sec)

笔记年龄必须最后更新。没有快捷键可以键入所有可更新的列。如果年龄以外的列是动态的,那么可能值得查看动态 sql。另一种方法可能是使用触发器将插入加载到临时表中以更新主表。

【讨论】:

  • 谢谢,但我实际上尝试了不同的做法,因为如果我们有 100 列,这不会扩展。然后我们必须为所有列复制col98 = if(VALUES(age) > age,values(col98),col98);
  • @andreas 似乎是数据/结构问题,在原始问题中根本没有提及。
  • 您需要重新审视描述数据结构的问题。
  • @FrankerZ 没有提到它是正确的。我只是希望我提供的示例非常简单,只是为了专注于我想要 conditional ON DUPLICATE KEY UPDATE
  • 感谢@FrankerZ 的反馈。我的问题已更新
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-21
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多