mysql - 如何在MySQL中进行动态限制?

标签 mysql sql sql-limit

我有一个这样的表:

// notifications
+----+--------------+------+---------+------------+
| id |      event   | seen | id_user | time_stamp |
+----+--------------+------+---------+------------+
| 1  | vote         | 1    | 123     | 1464174617 |
| 2  | comment      | 1    | 456     | 1464174664 |
| 3  | vote         | 1    | 123     | 1464174725 |
| 4  | answer       | 1    | 123     | 1464174813 |
| 5  | comment      | NULL | 456     | 1464174928 |
| 6  | comment      | 1    | 123     | 1464175114 |
| 7  | vote         | NULL | 456     | 1464175317 |
| 8  | answer       | NULL | 123     | 1464175279 |
| 9  | vote         | NULL | 123     | 1464176618 |
+----+--------------+------+---------+------------+ 

我正在尝试为特定用户选择至少 15 行。只是有两个条件:

  1. 始终应匹配所有未读行 (seen = NULL),即使它们超过 15 行。

  2. 如果未读行数超过 15,则还应选择 2 个已读行(seen = 1)。


示例: read 是已读行数,unreadnotifications 中未读行数表。

 read | unread |          output should be           
------|--------|-------------------------------------
 3    | 8      | 11 rows                             
 12   | 5      | 15 rows (5 unread, 10 read)         
 20   | 30     | 32 rows (30 unread, 2 read)         
 10   | 0      | 10 rows (0 unread, 10 read)         
 10   | 1      | 11 rows (1 unread, 10 read)         
 10   | 6      | 15 rows (6 unread, 9 read)          
 100  | 3      | 15 rows (3 unread, 12 read)         
 3    | 100    | 102 rows (100 unread, 2 read)       

这是我当前的查询,它不支持第二个条件。

SELECT id, event, seen, time_stamp 
 FROM notifications n
 WHERE id_user = :id AND seen IS NULL
) UNION 
(SELECT id, event, seen, time_stamp 
 FROM notifications n
 WHERE id_user = :id 
 ORDER BY (seen IS NULL) desc, time_stamp desc
 LIMIT 15
)
ORDER BY (seen IS NULL) desc, time_stamp desc;

最佳答案

只需选择所有看不见的和(与)15 个看到的。

SELECT id, event, seen, time_stamp 
 FROM notifications n
 WHERE id_user = :id AND seen IS NULL
UNION ALL
(SELECT id, event, seen, time_stamp 
 FROM notifications n
 WHERE id_user = :id AND seen IS NOT NULL
 LIMIT 15)

因此,您现在拥有所有未读通知和最多 15 条已读通知。

之后,如果看不见的少于 15 个,您可以将(客户端)截断为 15 个。

我认为最好的地方是获取循环。
只需计算已见/未见,并在达到足够行数时打破循环。

一些伪代码 php:

$read = $unread = 0;

while($row = $db->fetch()) {
  if ($row['seen']) $read++;
  if (!$row['seen']) $unread++;
  // ...
  if ($weHaveEnoughRows) break;
}

关于mysql - 如何在MySQL中进行动态限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37466913/

相关文章:

php - 如何在 MySQL 表的列中找到最常见的结果

mysql - Select * vs Select count(*),哪个统计行更快?

mysql将结果限制为每行的第一个短语

sql - 如何为 Oracle 中给定列中的每个不同值返回 1 行?

mysql - 如何用两个必需参数和一个可选参数连接两个表?

php - 从 ActionScript 3 到 MySQL 的 ByteArray -> 通过 ZendAMF 的 PHP

php - 将超链接附加到动态表格单元格

mysql - 两列组合唯一的 SQL 查询(带子查询)

mysql - 我应该添加额外的日期列吗?

php - 如何在连接多个表的查询中优化 MySQL "Order By Limit 1"?