我有这张表:
// 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/