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_id=36202417)某天的消费记录来说明,创建下面的临时表记录初始数据。
然后创建一张汇总表,用来记录玩家总的消费金额,为了能够使用insert into on duplicate key
update,汇总表一定要有主键,以player_id为主键:
为了使用insert into on duplicate key update进行对比分析,先在汇总表插入一条记录,总的消费金额设置为0
使用insert into on duplicate key update对amount进行汇总
insert into on duplicate key
update汇总结果是197,这个值是正确的汇总值。使用该方法对字段进行分组汇总的时候,数据不用提前汇总。
将汇总值重新置为0,使用update inner join进行汇总(其实就是更新了)
从结果可以看出,update inner join只对匹配上的记录进行了一次更新,即使上面的语句已经指定了set
a.total_amount=a.total_amount+b.amount,**update inner
join只会保留第一条匹配上的记录,之后匹配上的都会被丢弃**。所以在使用该方法一定要注意提前对数据进行分组汇总。
示例数据集:
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 |
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中的integer 数据类型
- MySQL存储过程
- mysql中int、bigint、smallint 和 tinyint的区别与长度
- mysql load data 导出、导入 csv
- source命令执行SQL脚本文件
- MySQL创建用户及权限控制
- MySQL管理数据表
- linux下mysql添加用户
- mysql procedure
- mysql触发器
- MySQL 备份和恢复策略
- mac下安装mysql(转载)
- mysql 修改编码 Linux/Mac/Unix/通用(杜绝修改后无法启动的情况!)
- MySQL数据的导出、导入(mysql内部命令:mysqldump、mysql)
- mysql数据行转列
- Linux下修改MySQL编码的方法
- MySQL Server 日志
- MySQL 安全事宜
- MySQL 备份与恢复