复合加入Sql查询与计时器

时间:2014-10-27 14:40:31

标签: mysql sql pdo cron

我有3张桌子

日志

|id| channel_id | date | content_id |
|1 | 3          | <ts> | 1          |
|1 | 3          | <ts> | 2          |
|1 | 4          | <ts> | 4          |

信道

|id|  channel_id | limit_repeat_time    | limit_timer | limit_count |  last_update 
|1 | 3           | 60                   | 1440        | 50          |  <timestamp>
|1 | 4           | 60                   | 1440        | 50          |  <timestamp>

队列

|id| channel_id  | content_id
|1 | 3           |   1
|1 | 3           |   2
|1 | 4           |   4

我有一个crontab检查这个表和循环,并得到我必须更新的频道列表;

频道几乎没有选择 1)limit_repeat时间:这意味着这个cron无法更新此通道小于此min; exc:如果这个是60,你每小时只能更新一次这个频道。 2)limit_timer和limit_count这是一个完整的限制计数。喜欢; limit_timer = 1440 limit_count = 50这意味着你每天最多可以添加50个内容(1440分钟)

我需要的是什么 我想找到未更新的频道,并且没有更多地插入

中的内容

我的cron设置为每分钟,所以我想每分钟运行一次这个查询,并且需要更新频道。

提前致谢!

3 个答案:

答案 0 :(得分:1)

我相信这就是你要找的东西。它从queue中选择满足两个标准的记录:

1)DATE_ADD(MAX(l.date), INTERVAL ch.limit_repeat_time MINUTE)<=NOW() - 检查log表中的最后一条记录是否至少比当前系统时间早ch.limit_repeat_time分钟。

2)(SELECT COUNT(*) FROM logs l1 WHERE DATE(l1.date) = DATE(NOW()) AND l1.channel_id=q.channel_id ) <=ch.limit_count

确保当前ch.limit_count表中特定channel的记录不超过logs条。

在你的例子中你的ID字段有点混乱 - 总是等于1,我不相信这是真实的数据。另请注意,为什么Channels表格有channel_idid。对我来说似乎没有必要。

整个选择:

SELECT q.channel_id, q.content_id

FROM `queue` AS q
INNER JOIN `channels` ch
ON ch.channel_id=q.channel_id 
LEFT JOIN `logs` l 
   ON l.channel_id=q.channel_id 

GROUP BY q.channel_id, q.content_id, ch.limit_repeat_time, ch.limit_count
HAVING (MAX(l.date) IS NULL OR
DATE_ADD(MAX(l.date), INTERVAL ch.limit_repeat_time MINUTE)<=NOW())
AND
IFNULL((SELECT COUNT(*) FROM `logs` l1
        WHERE DATE(l1.date) = DATE(NOW())
        AND l1.channel_id=q.channel_id ),0)
<ch.limit_count

请参阅此SQL Fiddle

此查询未涵盖这种情况,当您已经处理了49个项目并且队列中有10个新项目时 - 将返回所有10个新队列项目,因此您必须执行{{{ 1}}添加新项目时

如果您在插入新记录后仍然更新limit_count属性,也可以简化此查询。

channel.last_update

答案 1 :(得分:0)

我不认为你正在解释你想要做的事情,但是这会让你正在寻找。

SELECT
    *
FROM 
    `channels` AS c
WHERE
    DATE_ADD(c.`last_update`, INTERVAL c.`limit_repeat_time` MINUTE) > NOW()
AND c.limit_count < (
    SELECT 
        COUNT(*)
    FROM
        `logs` AS l
    WHERE
        l.`channel_id` = 3
    AND l.`date` BETWEEN DATE_SUB(NOW(), INTERVAL c.`limit_timer` MINUTE) AND NOW()
);

答案 2 :(得分:0)

如果

,您可以使用此解决limit_time
DECLARE limit_time_var integer;
SELECT limit_repeat_time INTO limit_time_var FROM channels 
       WHERE id=1 and channel_id=3;

if (((hour(curtime())* 60) + (minute(curtime()))) % limit_repeat_time = 0)
    then
    --Query time and count according to that day interval. I couldn't understand what is log and queue. If it is smaller than you expect then insert.
end if;