您的位置:首页 > 数据库 > MySQL

insert into on duplicate key update与update inner join使用效果对比分析

2016-01-18 14:21 796 查看
本文针对mysql的语法进行说明,我近期在使用mysql做数据统计的时候,总结了一下insert into on duplicate key update与update inner join的使用效果差异,通过下面的例子详细说明:

示例数据集:

player_idtimeamount
362024172016-01-17 17:40:1725
362024172016-01-17 17:47:2468
362024172016-01-17 17:49:466
362024172016-01-17 17:53:2868
362024172016-01-17 17:58:1930
首先创建玩家的消费记录表,然后对玩家的消费数据进行汇总,为了简单起见,这里只用一个玩家player_id=36202417)某天的消费记录来说明,创建下面的临时表记录初始数据。

mysql> CREATE TABLE tmp_player_pay_records (
->   player_id int(11) DEFAULT NULL,
->   time datetime DEFAULT NULL,
->   amount double DEFAULT NULL
-> );
Query OK, 0 rows affected (0.00 sec)

mysql> insert into tmp_player_pay_records values(36202417,'2016-01-17 17:40:17',25);
Query OK, 1 row affected (0.00 sec)

mysql> insert into tmp_player_pay_records values(36202417,'2016-01-17 17:47:24',68);
Query OK, 1 row affected (0.00 sec)

mysql> insert into tmp_player_pay_records values(36202417,'2016-01-17 17:49:46', 6);
Query OK, 1 row affected (0.00 sec)

mysql> insert into tmp_player_pay_records values(36202417,'2016-01-17 17:53:28',68);
Query OK, 1 row affected (0.00 sec)

mysql> insert into tmp_player_pay_records values(36202417,'2016-01-17 17:58:19',30);
Query OK, 1 row affected (0.00 sec)

mysql> select * from tmp_player_pay_records;
+-----------+---------------------+--------+
| player_id | time                | amount |
+-----------+---------------------+--------+
|  36202417 | 2016-01-17 17:40:17 |     25 |
|  36202417 | 2016-01-17 17:47:24 |     68 |
|  36202417 | 2016-01-17 17:49:46 |      6 |
|  36202417 | 2016-01-17 17:53:28 |     68 |
|  36202417 | 2016-01-17 17:58:19 |     30 |
+-----------+---------------------+--------+
5 rows in set (0.00 sec)


然后创建一张汇总表,用来记录玩家总的消费金额,为了能够使用insert into on duplicate key

update,汇总表一定要有主键,以player_id为主键:

mysql> CREATE TABLE tmp_player_total_pay (
->   player_id int(11) DEFAULT NULL,
->   total_amount double DEFAULT NULL,
->   primary key (player_id)
-> );
Query OK, 0 rows affected (0.00 sec)


为了使用insert into on duplicate key update进行对比分析,先在汇总表插入一条记录,总的消费金额设置为0

mysql> insert into tmp_player_total_pay values(36202417,0);
Query OK, 1 row affected (0.00 sec)

mysql> select * from tmp_player_total_pay;
+-----------+--------------+
| player_id | total_amount |
+-----------+--------------+
|  36202417 |            0 |
+-----------+--------------+
1 row in set (0.01 sec)


使用insert into on duplicate key update对amount进行汇总

mysql> insert into tmp_player_total_pay
-> select player_id,amount from tmp_player_pay_records
-> on duplicate key update
-> tmp_player_total_pay.total_amount=tmp_player_total_pay.total_amount+values(total_amount);
Query OK, 10 rows affected (0.01 sec)
Records: 5  Duplicates: 5  Warnings: 0


insert into on duplicate key

update汇总结果是197,这个值是正确的汇总值。使用该方法对字段进行分组汇总的时候,数据不用提前汇总。

mysql> select * from tmp_player_total_pay;
+-----------+--------------+
| player_id | total_amount |
+-----------+--------------+
|  36202417 |          197 |
+-----------+--------------+
1 row in set (0.00 sec)


将汇总值重新置为0,使用update inner join进行汇总(其实就是更新了)

mysql> update tmp_player_total_pay set total_amount=0 where player_id='36202417';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from tmp_player_total_pay;
+-----------+--------------+
| player_id | total_amount |
+-----------+--------------+
|  36202417 |            0 |
+-----------+--------------+
1 row in set (0.00 sec)

mysql> update tmp_player_total_pay a
-> inner join tmp_player_pay_records b on a.player_id=b.player_id
-> set a.total_amount=a.total_amount+b.amount;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0


从结果可以看出,update inner join只对匹配上的记录进行了一次更新,即使上面的语句已经指定了set

a.total_amount=a.total_amount+b.amount,**update inner

join只会保留第一条匹配上的记录,之后匹配上的都会被丢弃**。所以在使用该方法一定要注意提前对数据进行分组汇总。

mysql> select * from tmp_player_total_pay;
+-----------+--------------+
| player_id | total_amount |
+-----------+--------------+
|  36202417 |           25 |
+-----------+--------------+
1 row in set (0.00 sec)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql update