1
Layne 2016-07-27 00:38:48 +08:00
不知道数据量有多少,用 exists 和 not exists 会不会在效率上有巨大差异,
另外,没有环境验证,不确定能不能执行,我只是个数据渣… update user u set u.money = 0.5 * u.money where u.membergroupids != 27 and u.money > 0 and exists ( select 1 from thread t where t.postuserid = u.userid and t.dateline between date_add(now(), interval -4 month) and date_add(now(), interval -4 month) and t.forumid in (56,57,60,62,67,65,70,71,73,178,75,76,77,109,189,186,81,83,88,89,74,175,181,85,74,175,79,80,165,193,172,59) ); update user u set u.money = 0.5 * u.money where u.membergroupids != 27 and u.money > 0 and not exists ( select 1 from thread t where t.postuserid = u.userid and t.forumid in (56,57,60,62,67,65,70,71,73,178,75,76,77,109,189,186,81,83,88,89,74,175,181,85,74,175,79,80,165,193,172,59) ); |
2
oclock 2016-07-27 08:55:21 +08:00
查询条件这么复杂,建议把逻辑拆出来放进 with CTE 或者临时表
|
3
former 2016-07-27 09:43:26 +08:00
取出 dataline 最大的值,直接 select MAX(dataline) from table where 条件 就可以
|
4
adv007 2016-07-27 09:56:48 +08:00 via iPhone
不要在 sql 中做复杂逻辑,抽到程序里面,你会发现整个世界都是清晰的
|
5
wangyu1314 OP @Layne
感谢,两条都可以执行,但是第一条没有结果。第二条有。 1 queries executed, 1 success, 0 errors, 0 warnings 查询: update user u set u.money = 0.5 * u.money where u.membergroupids != 27 and u.money > 0 and exists ( select 1 from thread t where... 共 0 行受到影响 执行耗时 : 2.945 sec 传送时间 : 0 sec 总耗时 : 2.946 sec 1 queries executed, 1 success, 0 errors, 0 warnings update user u set u.money = 0.5 * u.money where u.membergroupids != 27 and u.money > 0 and not exists ( select 1 from thread t where t.postuserid = u.userid and t.forumid in (56,57,60,62,67,65,70,71,73,178,75,76,77,109,189,186,81,83,88,89,74,175,181,85,74,175,79,80,165,193,172,59) ); 查询: update user u set u.money = 0.5 * u.money where u.membergroupids != 27 and u.money > 0 and not exists ( select 1 from thread t w... 共 23176 行受到影响 执行耗时 : 3.634 sec 传送时间 : 0 sec 总耗时 : 3.634 sec |
6
wangyu1314 OP |
7
Layne 2016-07-27 11:02:38 +08:00
@wangyu1314 写 update 时,可以先把查询逻辑部分写好,然后更新需要处理的字段,以我写的第一句来看,查询逻辑为:
select * from /*update*/ user u /* set u.money = 0.5 * u.money */ where u.membergroupids != 27 and u.money > 0 and exists ( select 1 from thread t where t.postuserid = u.userid and t.dateline between date_add(now(), interval -4 month) and date_add(now(), interval -4 month) and t.forumid in (56,57,60,62,67,65,70,71,73,178,75,76,77,109,189,186,81,83,88,89,74,175,181,85,74,175,79,80,165,193,172,59) ); 调整这个查询逻辑,直到能查询出你需要更新的数据,然后再 update 对应字段即可。 写 update 语句时我一般习惯不用表关联,如果查询逻辑本身就特别复杂,就用存储过程来处理,或者用程序来处理了。 |
8
wangyu1314 OP @Layne 改出来了,但是这个思路是错的,这个语句会导致用户如果每个月都发了新主题的,会被重复扣钱。我们有 3 条规则, 1 - 3 个月扣多少, 3 - 6 扣多少, 6 个月以上扣多少。
|
9
wangyu1314 OP 这个语句只能找在技术区的所发主题的最大 dateline ,只对这个用户操作一次。
|
10
Layne 2016-07-27 13:15:42 +08:00
@wangyu1314
试试这样: select * from /*update*/ user u /* set u.money = 0.5 * u.money */ where u.membergroupids != 27 and u.money > 0 and exists ( select max(t.dateline) from thread t where t.postuserid = u.userid and t.forumid in (56,57,60,62,67,65,70,71,73,178,75,76,77,109,189,186,81,83,88,89,74,175,181,85,74,175,79,80,165,193,172,59) ) between date_add(now(), interval -4 month) and date_add(now(), interval -4 month) ; |
11
wangyu1314 OP @Layne
SELECT * FROM /*update*/ USER u /* set u.money = 0.5 * u.money */ WHERE u.membergroupids != 27 AND u.money > 0 AND EXISTS ( SELECT MAX(t.dateline) FROM thread t WHERE t.postuserid = u.userid AND t.forumid IN (56,57,60,62,67,65,70,71,73,178,75,76,77,109,189,186,81,83,88,89,74,175,181,85,74,175,79,80,165,193,172,59) ) BETWEEN DATE_ADD(NOW(), INTERVAL 4 MONTH) AND DATE_ADD(NOW(), INTERVAL 1 MONTH) ; 运行了以后没结果。 这种最大化取值 MAX(dateline)我试过了,只能取出一个全局最大值,不能取出每个人的最大值,而是这种取出值 不能参与运算。 |
12
Layne 2016-07-27 14:27:53 +08:00
把 exists 去掉呢?
自查询限制了 postuserid = userid ,取得的 max(dateline) 应该就是对应用户的最大值 |
13
wangyu1314 OP @Layne 去掉 exists 仍然没有效果。。。
|
14
Layne 2016-07-27 14:53:54 +08:00
@wangyu1314 看一下 between 语句后面的月份加减对不对,我用的是 date_add 函数,然后前溯的话应该是负数参数,或者用你习惯的日期函数来写
|
15
wangyu1314 OP 我用另外一种 方法取出了 thread 表每个用户的最大 dateline.
SELECT postuserid,FROM_UNIXTIME(dateline) FROM thread WHERE forumid IN (56,57,60,62,67,65,70,71,73,178,75,76,77,109,189,186,81,83,88,89,74,175,181,85,74,175,79,80,165,193,172,59) GROUP BY postuserid ORDER BY dateline DESC |
16
adv007 2016-07-27 17:37:40 +08:00 via iPhone
@wangyu1314 学学呗,你想想你这条语句遇到大并发的执行效率
|
17
msg7086 2016-07-28 07:20:50 +08:00
用关系数据库的 SQL 来跑业务逻辑只会更慢吧。
要不写存储过程? |