在插入之前如何计算一些东西?

时间:2016-06-29 18:04:14

标签: mysql sql

我有这张桌子:

// cookies
+---------+-------------------------+------------------+------------+
|   id    |         email           |     cookie       | date_time  |
+---------+-------------------------+------------------+------------+
| int(11) |      varchar(50)        |   varchar(128)   |  int(11)   |
+---------+-------------------------+------------------+------------+
| 1       | jack_2009@gmail.com     | ojer0f934mf2...  | 1467204523 |
| 2       | peter.zm@yahoo.com      | ko4398f43043...  | 1467205521 |
| 3       | matrix_john23@gmail.com | 34fjkg3j438t...  | 1467205601 |
| 4       | peter.zm@yahoo.com      | 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 )

那么,我该如何添加其他条件?

2 个答案:

答案 0 :(得分: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 ;

答案 1 :(得分:1)

我不确定>(在小组中)是否应该是>=,但我认为这会做你所要求的。

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
    )
;
  • 通过使用now() - INTERVAL 1 HOUR|DAY|MONTH查找最后一个小时|天|月的时间来计算在过去一小时|日|月中具有date_time值的所有行(对于电子邮件),并计算发生的值在那些开始时间之后。
  • 然后使用HAVING仅产生单数结果(聚合如COUNT没有关联的GROUP BY子句总是导致1行),如果有的话超出了您指定的限制。
  • 如果没有结果,NOT EXISTS会返回true(因为没有超出限制)。

编辑:根据需要更新比较以使用单位时间戳。