MySQL/MariaDB基于条件的重复密钥更新

MySQL/MariaDB基于条件的重复密钥更新,mysql,sql,mariadb,Mysql,Sql,Mariadb,我想使用有条件的 关于重复密钥更新 根据中提供的示例,假设name是主键。我们要执行以下查询: INSERT INTO beautiful (name, age, col3, col 4, ..., col 100) VALUES ('Helen', 24, ...), ('Katrina', 21, ...), ('Samia', 22, ...), ('Hui Ling', 25, ...), ('Yumie', 29, ...) ON DUP

我想使用有条件的

关于重复密钥更新

根据中提供的示例,假设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中),我希望只在新收到的记录的年龄大于数据库中已经存在的记录的年龄时才进行更新

有办法做到这一点吗

更新:更新以反映每个记录都有多个字段这一事实

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)
注:年龄必须最后更新。没有快捷方式为所有可更新列设置键。如果除age之外的列是动态的,那么就值得研究动态sql。另一种方法可能是使用触发器将插入加载到暂存表,以更新主表

似乎微不足道

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)

注:年龄必须最后更新。没有快捷方式为所有可更新列设置键。如果除age之外的列是动态的,那么就值得研究动态sql。另一种方法可能是使用触发器将插入加载到暂存表,以更新主表

是的,有一个trigger是的,有一个trigger谢谢,但我实际上尝试了不同的方法,因为如果我们有100列,这不会缩放。然后我们必须复制
col98=if(VALUES(age)>age,VALUES(col98),col98)适用于所有columns@andreas似乎是一个数据/结构问题,在原始问题中根本没有提及。您需要重新审视您描述数据结构的问题。@FrankerZ您没有提及这一点是正确的。我只是希望我提供的示例非常简单,只是为了关注这样一个事实,即我想要一个重复键UpdateAnks@FrankerZ作为反馈的条件。我的问题是更新了Hanks,但实际上我尝试了不同的做法,因为如果我们有100列,这不会缩放。然后我们必须复制
col98=if(VALUES(age)>age,VALUES(col98),col98)适用于所有columns@andreas似乎是一个数据/结构问题,在原始问题中根本没有提及。您需要重新审视您描述数据结构的问题。@FrankerZ您没有提及这一点是正确的。我只是希望我提供的示例非常简单,只是为了关注这样一个事实,即我想要一个重复键UpdateAnks@FrankerZ作为反馈的条件。我的问题更新了