海洋cms每天随机发布多部电影。
案列:存放了一些电影资源在隐藏电影里面,然后每天数据库自动随机发几部。比如我们每天晚上8点随机发10部。并要将时间更新为当前时间。
开始记录代码过程:
①先研究数据库字段,电影数据表,电影id字段,电影隐藏和发布状态实现字段;
数据库表里面的v_recycled字段 已发布值为0 隐藏状态值为1
v_addtime字段为发布时间时间戳
所以将隐藏电影还原sql代码是:
UPDATE `电影数据表` SET `v_recycled` = '1' WHERE `电影数据表`.`v_id` = 电影id;
②sql随机筛选多条数据代码是:如数据库随机筛选10条已隐藏电影
SELECT * FROM `电影数据表` WHERE `电影数据表`.`v_recycled` = '1' ORDER BY RAND() LIMIT 10
但是我想隐藏电影按顺序发布,于是我用的是:
SELECT * FROM `电影数据表` WHERE `电影数据表`.`v_recycled` = '1' LIMIT 10
我只需要id作为
SELECT v_id FROM `电影数据表` WHERE `电影数据表`.`v_recycled` = '1' LIMIT 10
用以上代码先尝试查询数据,代码和查询的数据都是正确的
③开始编辑修改代码
UPDATE `电影数据表` SET `v_recycled` = '0' WHERE v_id IN (SELECT v_id FROM `电影数据表` WHERE `电影数据表`.`v_recycled` = '1' LIMIT 10)
这个有错误提示:This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME subquery’,
百度原因发现是:
因为原因在于子查询三层嵌套在 in或 not in 中使用了 limit
但是再加上一层,绕开limit子查询就可以了!
修改代码:
筛选出10个
SELECT v_id FROM `电影数据表` WHERE v_id IN(SELECT v_id FROM `电影数据表` WHERE `电影数据表`.`v_recycled` = '1' )LIMIT 10
修改筛选出的10个电影的发布状态值和时间修改为当前时间戳
UPDATE `电影数据表` SET `v_recycled` = '0' , v_addtime = CURRENT_TIMESTAMP WHERE v_id IN(SELECT v_id FROM `电影数据表` WHERE `电影数据表`.`v_recycled` = '1' )LIMIT 10
出现错误提示 :1093 – You can’t specify target table ‘result’ for update in FROM clause
翻译为:不能先select出同一表中的某些值,再update这个表(在同一语句中)
也就是说:需要把结果集当作一个表,自我查询一遍
再次修改
UPDATE `电影数据表` SET `v_recycled` = '0' , v_addtime = CURRENT_TIMESTAMP WHERE v_id IN(select v_id from(SELECT v_id FROM `电影数据表` WHERE `电影数据表`.`v_recycled` = '1' LIMIT 10)as a )
错先错误提示,查看后台是更新时间不对 应该是用错时间戳了
Warning: #1264 Out of range value for column ‘v_addtime’ at row 13780
最终成功修改代码是
UPDATE `电影数据表` SET `v_recycled` = '0' , v_addtime = unix_timestamp(now()) WHERE v_id IN(select v_id from(SELECT v_id FROM `电影数据表` WHERE `电影数据表`.`v_recycled` = '1' LIMIT 10)as a )
如果按照id从打到小发布(即先发布最新的隐藏电影)
UPDATE `电影数据表` SET `v_recycled` = '0' , v_addtime = unix_timestamp(now()) WHERE v_id IN(select v_id from(SELECT v_id FROM `电影数据表` WHERE `电影数据表`.`v_recycled` = '1'ORDER BY `v_id` DESC LIMIT 10)as a )
然后登录数据库root账户设置事件 参考 ☞ 设置数据库事件教程和常见问题
参考文档:
1.感谢海洋cms官方网站
2.百度几个错误提示
以下内容为参考的文章
参考文章内容一:
MySQL常见错误:“You can‘t specify target table ‘test‘ for update in FROM clause”
有表如下:
要求删除 除了id不同 其余都相同的学生数据:
写出如下SQL以后,
DELETE FROM test WHERE id not in(
SELECT id from test GROUP BY name,course,score );
报错如下:
意为:不能先查出同一个表中的数据以后再进行更新
解决方法是再将这些数据通过中间表select一遍即可:
DELETE FROM test WHERE id not in(
SELECT id FROM(
SELECT id from test GROUP BY name,course,score )as a);
修改一定要注意中英文符号,我就被坑了好久没发现特别是括号
执行结果为:
参考文章内容二:
mysql 随机修改几条数据
本节主要内容:
mysql随机查询
在mysql中查询5条不重复的数据,使用:
复制代码 代码示例:
SELECT * FROM `table` ORDER BY RAND() LIMIT 5
不过这样的效率非常低。一个15万余条的库,查询5条数据,居然要8秒以上
网上基本上都是查询max(id) * rand()来随机获取数据。
例如:
复制代码 代码示例:
SELECT *
FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM `table`)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id ASC LIMIT 5;
不过,这样会产生连续的5条记录。
解决办法:
只能是每次查询一条,查询5次。即便如此也值得,因为15万条的表,查询只需要0.01秒不到。
上面的语句采用的是JOIN,mysql的论坛上有人使用:
复制代码 代码示例:
SELECT *
FROM `table`
WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` )
ORDER BY id LIMIT 1;
测试结果:
需要0.5秒,速度也不错,但是跟上面的语句还是有很大差距。总觉有什么地方不正常。
于是修改语句为:
复制代码 代码示例:
SELECT * FROM `table`
WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM `table`)))
ORDER BY id LIMIT 1;
这下,效率又提高了,查询时间只有0.01秒
最后,再把语句完善一下,加上MIN(id)的判断。
我在最开始测试时,就是因为没有加上MIN(id)的判断,结果有一半的时间总是查询到表中的前面几行。
完整的查询语句:
复制代码 代码示例:
SELECT * FROM `table`
WHERE id >= (SELECT floor( RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`)) + (SELECT MIN(id) FROM `table`)))
ORDER BY id LIMIT 1;
SELECT *
FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`))+(SELECT MIN(id) FROM `table`)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id LIMIT 1;
最后,对这两个语句进行分别查询10次,
前者花费时间 0.147433 秒
后者花费时间 0.015130 秒
小结:采用JOIN的语法比直接在WHERE中使用函数效率还要高很多。