我有这张桌子:

// 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 )

好吧,我怎样才能增加其他条件呢?

最佳答案

我不确定(在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查找最后一个小时|天|月的开始时间,并计算在这些开始时间之后发生的值,来计算在最后一个小时|天|月中具有日期时间值的所有行(对于电子邮件)。
然后,如果超出了您指定的任何限制,它将使用HAVING只生成单一结果(聚合,例如没有关联的COUNT子句的GROUP BY总是在一行中产生)。
如果没有结果(因为没有超过限制),则NOT EXISTS返回true。
编辑:根据问题的需要,更新比较以使用单位时间戳。

关于mysql - 插入之前如何计数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38107025/

10-11 12:46