【问题标题】:How can I make a dynamic limit selecting?如何进行动态限制选择?
【发布时间】:2016-05-25 12:07:30
【问题描述】:

我有一张这样的桌子:

// 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 条未读消息)

如您所见,我正在尝试获取所有未读消息以及至少两条已读消息。默认情况下,行数应为 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

【问题讨论】:

    标签: mysql sql sql-limit


    【解决方案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(抱歉,我没有给你投票,因为我没有足够的代表)。我会接受你的回答。
    • 但只有一件事:正如我所提到的,我总是需要在未读消息的末尾有两条已读消息。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-24
      • 2019-04-26
      • 2012-05-15
      • 1970-01-01
      • 2013-03-06
      • 1970-01-01
      • 2013-12-22
      • 1970-01-01
      相关资源
      最近更新 更多