2016-06-29 87 views
1

我有這個表:如何在插入前計算一些東西?

// cookies 
+---------+-------------------------+------------------+------------+ 
| id |   email   |  cookie  | date_time | 
+---------+-------------------------+------------------+------------+ 
| int(11) |  varchar(50)  | varchar(128) | int(11) | 
+---------+-------------------------+------------------+------------+ 
| 1  | [email protected]  | ojer0f934mf2... | 1467204523 | 
| 2  | [email protected]  | ko4398f43043... | 1467205521 | 
| 3  | [email protected] | 34fjkg3j438t... | 1467205601 | 
| 4  | [email protected]  | 0243hfd348i4... | 1467206039 | 
+---------+-------------------------+------------------+------------+ 

這裏是我的查詢:

INSERT INTO cookies VALUES(NULL, $email, $hash, unix_timestamp()) 

現在我需要在插入之前先檢查以下條件

的(對數特定用戶)應小於:

  • 5每小時
  • 10每天
  • 50每月
  • 100佔總

我可以檢查最後一種情況:

INSERT INTO cookies(id, email, cookie, date_time) 
SELECT NULL, $email, $hash, unix_timestamp() 
FROM cookie 
WHERE email = $email AND 
     100 >= (SELECT count(1) FROM cookies WHERE email = $email) 

好,我怎麼能廣告其他條件?

+0

'id'是否對應一個唯一的用戶? –

+0

你可以使用存儲過程,並且你可以處理這個 –

+0

@vkp'id'列是PK *(所以它是唯一的)*。但是'email'列不是唯一的。 – stack

回答

1

我不是在>是否的(在group by)應該是>=的積極的,但我認爲這會做你的要求。

INSERT INTO cookies(id, email, cookie, date_time) 
SELECT NULL, $email, $hash, unix_timestamp() 
FROM cookie 
WHERE email = $email 
    AND NOT EXISTS (
     SELECT COUNT(CASE WHEN date_time > UNIX_TIMESTAMP(now() - INTERVAL 1 HOUR) 
          THEN 1 ELSE NULL END) AS rowsInLastHour 
      , COUNT(CASE WHEN date_time > UNIX_TIMESTAMP(now() - INTERVAL 1 DAY) 
          THEN 1 ELSE NULL END) AS rowsInLastDay 
      , COUNT(CASE WHEN date_time > UNIX_TIMESTAMP(now() - INTERVAL 1 MONTH) 
         THEN 1 ELSE NULL END) AS rowsInLastMonth 
      , COUNT(1) AS rowsEver 
     FROM cookie 
     WHERE email = $email 
     HAVING rowsInLastHour > 5 
      OR rowsInLastDay > 10 
      OR rowsInLastMonth > 50 
      OR rowsEver > 100 
    ) 
; 
  • 它計數所有,在最後一小時有DATE_TIME值的行(用於電子郵件)|天|月通過now() - INTERVAL 1 HOUR|DAY|MONTH發現當最後一個小時|天|月開始,並計算這些值在那些開始時間之後發生。
  • 然後它使用HAVING僅產生單數結果(如COUNT沒有關聯GROUP BY子句的聚合總是導致1行),如果超出了指定的任何限制。
  • 然後,如果沒有結果,NOT EXISTS返回true(因爲沒有超出限制)。

編輯:根據問題需要更新比較以使用單位時間戳。

+0

好吧,這個查詢只檢查**最後的**或**任何**的? – stack

+0

最後一個,我會在編輯中添加細節/解釋。 – Uueerdo

+0

正如您在問題中看到的那樣,unix_time列的值是整數秒。但是'now() - INTERVAL ...'返回一個日期時間格式。那麼你認爲這會起作用嗎? 'date_time> now() - INTERVAL 1 HOUR' – stack

1

您可以使用存儲過程,並且可以在其中處理此問題。通過您的插入值,此存儲過程

DELIMITER $$ 
CREATE PROCEDURE `sp_test`(id int, email varchar(45), cookie varchar(45), date_time datetime) 
BEGIN 
DECLARE countval INT; 

SET countval = (SELECT sum(1) FROM cookies WHERE email = $email); 

IF (countval is null) THEN 
// do something 
ELSEIF (countval>10) THEN 
    // do something like that 
ELSE 
// do something 
END IF; 

// insert query 

END $$ 
DELIMITER ; 
+0

你可以叫它usin「調用sp_test(1,」sasa「,」wew「,3232);」 –