MySQL查询更改行是否更高?

时间:2018-12-11 16:09:21

标签: mysql

我有两个表(account2017和(account2018),我想在2行的名称末尾添加一个name表,但前提是两个表都包含相同的名称。为该名称添加2,其points值较低。

总体解决方案是合并具有唯一键(名称)的两个表,但要决定哪一行在其名称的末尾添加2,则应在其后加上小数点。

例如,如果表account2017和account2018在name列中都带有“ Alex”,则在该表的名称(= Alex2)的末尾添加一个2,该表中的值较低points列。由于accounts2017中的Alex有20分,accounts2018中的Alex只有15分,因此accounts2018的Alex名称将更改为Alex2。 Accounts2017将保持不变。

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

如果我的理解正确,听起来您需要使用2个单独的update语句,并使用exists来匹配条件:

update account2017
set name = concat(name, '2') 
where exists (
    select 1 
    from account2018 
    where account2017.name = account2018.name and account2017.score < account2018.score)

update account2018
set name = concat(name, '2') 
where exists (
    select 1 
    from account2017 
    where account2018.name = account2017.name and account2018.score < account2017.score)

答案 1 :(得分:0)

您需要在2个查询中执行此操作。语法取决于您使用的语法(MySQL,SQL Server,SQLite),但这是MySQL版本:

UPDATE accounts2017 table1 SET name = concat(name, '2') WHERE exists (SELECT 1 FROM accounts2018 table2 WHERE table1.name = table2.name AND table1.score < table2.score);

然后,您只需翻转查询即可更新2018表。

答案 2 :(得分:0)

您可以使用多表更新来执行此操作。这依赖于mysql认识到account2017尚未进行任何更改(时间戳未更改这一事实证明了这一点),但请注意在触发触发器之前和之后。

MariaDB [sandbox]> drop table if exists account2017,account2018;
Query OK, 0 rows affected (0.39 sec)

MariaDB [sandbox]> create table account2017(name varchar(10), points int,ts timestamp  DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.20 sec)

MariaDB [sandbox]> create table account2018(name varchar(10), points int,ts timestamp  DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.29 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> drop trigger if exists t;
Query OK, 0 rows affected, 1 warning (0.00 sec)

MariaDB [sandbox]> delimiter $$
MariaDB [sandbox]> create trigger t before update on account2017
    -> for each row
    -> begin
    -> insert into debug_table(msg) values (concat('before:',old.name,':',new.name));
    -> end $$
Query OK, 0 rows affected (0.07 sec)

MariaDB [sandbox]> delimiter ;
MariaDB [sandbox]>
MariaDB [sandbox]> drop trigger if exists t1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

MariaDB [sandbox]> delimiter $$
MariaDB [sandbox]> create trigger t1 after update on account2017
    -> for each row
    -> begin
    -> insert into debug_table(msg) values (concat('after:',old.name,':',new.name));
    -> end $$
Query OK, 0 rows affected (0.08 sec)

MariaDB [sandbox]> delimiter ;
MariaDB [sandbox]>
MariaDB [sandbox]> insert into account2017 (name,points) values('alex',20);
Query OK, 1 row affected (0.02 sec)

MariaDB [sandbox]> insert into account2018 (name,points) values('alex',15);
Query OK, 1 row affected (0.01 sec)

MariaDB [sandbox]> truncate table debug_table;
Query OK, 0 rows affected (0.17 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> select * from account2017;
+------+--------+---------------------+
| name | points | ts                  |
+------+--------+---------------------+
| alex |     20 | 2018-12-11 16:49:25 |
+------+--------+---------------------+
1 row in set (0.00 sec)

MariaDB [sandbox]> select * from account2018;
+------+--------+---------------------+
| name | points | ts                  |
+------+--------+---------------------+
| alex |     15 | 2018-12-11 16:49:25 |
+------+--------+---------------------+
1 row in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> select sleep(60);
+-----------+
| sleep(60) |
+-----------+
|         0 |
+-----------+
1 row in set (1 min 0.00 sec)

MariaDB [sandbox]> update account2017 join account2018 on account2017.name = account2018.name
    -> set account2017.name = case when account2017.points < account2018.points then concat(account2017.name,'2') else account2017.name end,
    ->     account2018.name = case when account2018.points < account2017.points then concat(account2018.name,'2') else account2018.name end
    -> where 1 = 1;
Query OK, 1 row affected (0.04 sec)
Rows matched: 2  Changed: 1  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]>
MariaDB [sandbox]>
MariaDB [sandbox]> select * from account2017;
+------+--------+---------------------+
| name | points | ts                  |
+------+--------+---------------------+
| alex |     20 | 2018-12-11 16:49:25 |
+------+--------+---------------------+
1 row in set (0.00 sec)

MariaDB [sandbox]> select * from account2018;
+-------+--------+---------------------+
| name  | points | ts                  |
+-------+--------+---------------------+
| alex2 |     15 | 2018-12-11 16:50:26 |
+-------+--------+---------------------+
1 row in set (0.00 sec)

MariaDB [sandbox]> select * from debug_table;
+----+------------------+------+
| id | msg              | MSG2 |
+----+------------------+------+
|  1 | before:alex:alex | NULL |
|  2 | after:alex:alex  | NULL |
+----+------------------+------+
2 rows in set (0.00 sec)