如何进行动态限制选择?

时间:2016-05-25 12:07:30

标签: 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 |
+----+--------------+------+---------+------------+ 

我正在尝试创建最近的收件箱邮件框。我想根据这个条件为每个用户提取读取和未读消息:

注意:在列表末尾始终应该至少有2条消息被读取(seen = 1)。

默认情况下,结果应包含15行。除非:

  • 还有13条未读消息(seen = NULL(加上两条已读取且始终存在的读取消息)
  • 所有邮件总共少于15个。

以下是一些示例:(阅读邮件:seen = 1,未读邮件:seen = NULL

    • 信息:阅读邮件:1,未读邮件:1
    • 输出 2行。 (包含一条读取消息和一条未读消息)
      • 信息:阅读留言:40,未读留言:1
      • 输出 15行。 (包含14条已读消息和1条未读消息)
        • 信息:阅读邮件:12,未读邮件:20
        • 输出 22行。 (包含2条已读消息和20条未读消息)
          • 信息:阅读留言:0,未读留言:16
          • 输出 16行。 (包含0条读取消息和16条未读消息)
            • 信息:阅读邮件:25,未读邮件:15
            • 输出 17行。 (包含2条读取消息和15条未读消息)
              • 信息:阅读留言:4,未读留言:8
              • 输出:12行。 (包含4条读取消息和8条未读消息)
                • 信息:阅读留言:745,未读留言:4
                • 输出 15行。 (包含11条已读消息和4条未读消息)
              1. 如您所见,我试图获取所有未读消息以及至少两条读取消息。此外,默认情况下,行数应为15。我怎么能这样做?

                这是我的问题:

                SELECT id, event seen, time_stamp 
                  FROM notifications
                 WHERE id_user = :id AND
                    LIMIT 15 OR IF (seen IS NULL > 15) THEN seen AND 
                                   SELECT id, event seen, time_stamp FROM notification
                                     WHERE id_user = :id AND seen IS NOT NULL LIMIT 2
                                ENDIF
                

2 个答案:

答案 0 :(得分:1)

一种方法很接近:

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

然而,这并没有得到所有看不见的消息。所以,这有点破解:

(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;

第一个子查询获取所有看不见的消息。第二个得到十五条消息。 UNION删除重复项,但不应用其他限制。我相信这可以做你想要的。

答案 1 :(得分:0)

在MySQL中不可能为LIMIT使用不同的值。

解决方法是计算LIMIT的值并将其保存到变量中,然后使用prepared statements