Php 获取上一小时或上20个项目的记录(如果在上一小时内没有记录)

Php 获取上一小时或上20个项目的记录(如果在上一小时内没有记录),php,mysql,node.js,Php,Mysql,Node.js,我有一个聊天系统,我想显示过去一个小时内发送的消息,但我也想显示最近20条消息,无论它们是在多长时间前发送的 有没有一种方法可以在SQL查询中实现这一点 CREATE TABLE IF NOT EXISTS `chat` ( `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `use

我有一个聊天系统,我想显示过去一个小时内发送的消息,但我也想显示最近20条消息,无论它们是在多长时间前发送的

有没有一种方法可以在SQL查询中实现这一点

CREATE TABLE IF NOT EXISTS `chat` (
  `id`        INT(11) UNSIGNED                                                                            NOT NULL AUTO_INCREMENT,
  `user_id`   INT(11) UNSIGNED                                                                            NOT NULL,
  `item_id`   INT(11) UNSIGNED                                                                            NOT NULL,
  `message`   TEXT                                                                                        NOT NULL,
  `recipient` INT(11)                                                                                     NOT NULL DEFAULT '0',
  `type`      ENUM ('message', 'announcement') NOT NULL DEFAULT 'message',
  `channel`   ENUM ('general', 'private')                                              NOT NULL DEFAULT 'general',
  `posted`    DATETIME                                                                                    NOT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `posted` (`posted`),
  KEY `type` (`type`),
  KEY `channel` (`channel`),
  KEY `recipient` (`recipient`)
)
  ENGINE = MyISAM
  DEFAULT CHARSET = `utf8`
  AUTO_INCREMENT = 2;
试试这个:

SELECT *
FROM `chat`
ORDER BY `posted` DESC
LIMIT 0,20;
它将按日期/时间列出最后20行。既然你想在最后一个小时内没有足够的时间进行更老的聊天,你就不必担心聊天的时间

以下内容未经测试,可能存在语法错误,因此您可能需要稍微处理一下

SELECT *
FROM `chat`
WHERE DATE_ADD(a.`posted` interval 1 hour) <= NOW()
UNION
(
    SELECT *
    FROM `chat`
    WHERE a.posted > DATE_SUB(NOW(), interval 1 hour)
    AND (SELECT count(*) FROM `chat` WHERE a.posted <= DATE_SUB(NOW(), interval 1 hour)) < 20
    ORDER BY `posted` DESC
    LIMIT 0,20)
ORDER BY `posted` DESC
只有当最后一小时内的帖子少于20篇时,它才应该添加比最后一小时早的帖子。

尝试以下方法:

SELECT *
FROM `chat`
ORDER BY `posted` DESC
LIMIT 0,20;
它将按日期/时间列出最后20行。既然你想在最后一个小时内没有足够的时间进行更老的聊天,你就不必担心聊天的时间

以下内容未经测试,可能存在语法错误,因此您可能需要稍微处理一下

SELECT *
FROM `chat`
WHERE DATE_ADD(a.`posted` interval 1 hour) <= NOW()
UNION
(
    SELECT *
    FROM `chat`
    WHERE a.posted > DATE_SUB(NOW(), interval 1 hour)
    AND (SELECT count(*) FROM `chat` WHERE a.posted <= DATE_SUB(NOW(), interval 1 hour)) < 20
    ORDER BY `posted` DESC
    LIMIT 0,20)
ORDER BY `posted` DESC

只有当最后一小时内的帖子少于20篇时,它才应该添加比最后一小时早的帖子。

这应该可以做到:

(
    select * from chat
    where timestamp > DATE_SUB(now(), interval 1 hour)
)
union
(   
    select * from chat order by posted desc limit 20
)
order by posted
说明:

它选择最近一小时的所有消息。 它还选择最后20条消息,因为单独查询20条记录速度很快 并集合并两个结果,并在两个结果重叠的情况下删除双重结果
因此,当在过去一小时内没有数据时,您仍然会收到最近的20篇帖子。如果在过去的一个小时里有很多数据,你会得到所有这些数据

这应该可以做到:

(
    select * from chat
    where timestamp > DATE_SUB(now(), interval 1 hour)
)
union
(   
    select * from chat order by posted desc limit 20
)
order by posted
说明:

它选择最近一小时的所有消息。 它还选择最后20条消息,因为单独查询20条记录速度很快 并集合并两个结果,并在两个结果重叠的情况下删除双重结果
因此,当在过去一小时内没有数据时,您仍然会收到最近的20篇帖子。如果在过去的一个小时里有很多数据,你会得到所有这些数据

显示该表的架构。@Sloarchasher抱歉,已添加架构。只是觉得没有那么大的帮助。一个简单的订单,以20个为上限,只会让你更容易写一个例子。答案。@Fred ii-这不是只显示最后一个小时内的最后20个项目吗?嘿,我试试看。显示表的模式。@Sloarthasher抱歉,添加了模式。只是觉得没有那么大的帮助。一个简单的订单,以20个为上限,只会让你更容易写一个例子。答案。@Fred ii-这不是只显示最后一个小时内的最后20个项目吗?嘿,我试试。那不是只显示最后20条信息吗?如果在最后一个小时内发送了100条消息呢?我想显示所有100条信息。是的,这将只显示最后20条。我可以重新编写以显示过去一小时内的所有内容,再加上过去一小时内的20个内容,当您在过去一小时内有足够的时间时,您可以在调用查询的代码中忽略这些内容。只是一个提示:不要执行日期添加。发布间隔1小时日期下,间隔1小时。它将产生相同的结果,但运行速度要快得多。您的版本需要为表中的每一行添加一个小时,这意味着也不会使用索引。那会慢得多。在大桌子上,这将是一个不同的世界。这不会只显示最后20条信息吗?如果在最后一个小时内发送了100条消息呢?我想显示所有100条信息。是的,这将只显示最后20条。我可以重新编写以显示过去一小时内的所有内容,再加上过去一小时内的20个内容,当您在过去一小时内有足够的时间时,您可以在调用查询的代码中忽略这些内容。只是一个提示:不要执行日期添加。发布间隔1小时日期下,间隔1小时。它将产生相同的结果,但运行速度要快得多。您的版本需要为表中的每一行添加一个小时,这意味着也不会使用索引。那会慢得多。在大桌子上,这将是一个不同的世界。这太棒了!谢谢这太好了!非常感谢。