2014-10-27 46 views
-1

我有3個表複雜的聯接SQL查詢隨着計時器

日誌

|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 time:這意味着這個cron不能更新這個通道小於這個分鐘; exc:如果這個是60,你只能每小時更新一次這個頻道。 2)limit_timer和limit_count這是一個完整的極限計數。喜歡; limit_timer = 1440 limit_count = 50,這是意味着你可以每天補充50含量最高(1440分鐘)

我需要的是 我想找個渠道不更新,並沒有在

insterted更多的則內容我cron設置爲每分鐘,所以我想每分鐘運行一次這個查詢,並且需要更新通道。

在此先感謝!

+0

'content_id'列代表什麼?這是添加到頻道的內容數量? – 2014-11-04 20:01:39

回答

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記錄在logs表該特定channel用於本一天。

在你的例子中你的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個新隊列項目都會返回,因此您必須執行limit_count的額外檢查添加新項目時。

如果您在插入新記錄後全部更新channel.last_update屬性,則還可以簡化此查詢。

SELECT q.channel_id, q.content_id 
FROM `queue` AS q 
INNER JOIN `channels` ch ON ch.channel_id=q.channel_id 
WHERE ch.last_update IS NULL OR 
     DATE_ADD(ch.last_update, INTERVAL ch.limit_repeat_time MINUTE)<=NOW() 
AND 
     (SELECT COUNT(*) FROM `logs` l1 
     WHERE DATE(l1.date) = DATE(NOW()) 
     AND l1.channel_id=q.channel_id) 
     <ch.limit_count; 
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() 
); 
+0

感謝您的回答,我的英語很抱歉。在這個sql代碼隊列中缺少sql應該檢查隊列中是否有任何隊列屬於用戶。 – 2014-11-01 09:47:35

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;