我有一个这样的表:
// 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 行。只是有两个条件:
始终应匹配所有未读行 (
seen = NULL
),即使它们超过 15 行。如果未读行数超过 15,则还应选择 2 个已读行(
seen = 1
)。
示例: read
是已读行数,unread
是notifications
中未读行数表。
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/