mysql - 我怎样才能在插入之前计算一些东西?

标签 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 )

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

最佳答案

我不确定 > 的(在 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
    )
;
  • 它通过使用 now() - INTERVAL 1 HOUR|DAY|MONTH 计算最后一小时|天|月内具有 date_time 值的所有行(对于电子邮件) hour|day|month 开始,并计算在这些开始时间之后发生的那些值。
  • 然后它使用 HAVING 只产生单一结果(如 COUNT 的聚合总是没有关联的 GROUP BY 子句结果在 1 行中),如果超出了您指定的任何限制。
  • 如果没有结果(因为没有超出限制),NOT EXISTS 返回 true。

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

关于mysql - 我怎样才能在插入之前计算一些东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38107025/

相关文章:

mySQL 从连接表中排除行

java - 数据库连接功能在 PHP 中实现

带索引的属性的 SQL 映射值

mysql - java.sql.BatchUpdateException : transaction too large, 长度:300200

MySQL计算无变量的运行总计

MySQL多对多,获取值

MySQL 错误 1264 : out of range value for column

用于获取最近 12 个月内付款演变图的 MySQL 查询

sql - T-SQL : Using a CASE in an UPDATE statement to update certain columns depending on a condition

sql - 程序-case语句错误