小编典典

插入之前如何计数?

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 )

好吧,我该如何添加其他条件?


阅读 201

收藏
2021-04-22

共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。

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

2021-04-22