1

我有一个看起来像这样的表:

create (DATETIME) |   Message (TEXT)
=========================================
2013-08-05 9:00:00  "Hi there!"
2013-08-05 10:00:00 "Hi again!"
2013-08-07 14:00:00 "Hi from the future!"

我希望能够获取所有消息并分组,DATE(create)以便消息按 分组2013-08-052013-08-07依此类推。这很容易通过以下方式完成ORDER BY

SELECT * FROM messages ORDER BY create

问题是我希望能够按组分页。例如,如果我有 10 个不同的日期,我想每页显示所有消息 5 个日期组并分页。

我已经看到了很多关于LIMIT组内元素数量的解决方案,但还没有看到任何LIMIT组数量的解决方案。

我基本上想要看起来像这样的结果:

如果LIMIT只显示 1 组:

2013-08-05 9:00:00  "Hi there!"
2013-08-05 10:00:00 "Hi again!"

如果LIMIT显示 2 组:

2013-08-05 9:00:00  "Hi there!"
2013-08-05 10:00:00 "Hi again!"
2013-08-07 14:00:00 "Hi from the future!"

如果LIMIT显示 1 组跳过第一个组:

2013-08-07 14:00:00 "Hi from the future!"

这如何在 SQL 中实现?

4

3 回答 3

0

你可以这样做

LIMITing 只显示 1 组:

SELECT created, message
  FROM messages m JOIN 
(
  SELECT MIN(created) min_created, MAX(created) max_created
    FROM
  (
    SELECT DATE(created) created
      FROM messages
     GROUP BY DATE(created)
     LIMIT 1 -- use LIMIT as you would normally do here
  ) z
) q
    ON m.created BETWEEN q.min_created AND q.max_created + INTERVAL 1 DAY;

输出:

+---------+------------+
| 创建 | 留言 |
+---------+------------+
| 2013-08-05 9:00:00 | 你好呀!|
| 2013-08-05 10:00:00 | 你好,我们又见面了!|
+---------+------------+

LIMIT显示 1 组跳过第一个:

SELECT  created, message
  FROM messages m JOIN 
(
  SELECT MIN(created) min_created, MAX(created) max_created
    FROM
  (
    SELECT DATE(created) created
      FROM messages
     GROUP BY DATE(created)
     LIMIT 1, 1 -- use LIMIT as you would normally do here
  ) z
) q
    ON m.created BETWEEN q.min_created AND q.max_created + INTERVAL 1 DAY;

输出:

+------------------+----------+
| 创建 | 留言 |
+------------------+----------+
| 2013-08-07 14:00:00 | 来自未来的你好!|
+------------------+----------+

注意:确保您在created列上有索引

这是SQLFiddle演示

于 2013-09-02T02:22:53.913 回答
0

我认为您需要计算组 ID 并limit手动执行:

SELECT m.*
FROM messages m join
     (select date(create) as createdate, count(*) as cnt, @rn := @rn + 1 as groupnum
      from messages m cross join (select @rn := 0) const
      group by date(create)
     ) md
     on date(m.create) = createdate
WHERE groupnum between 1 and 5;
于 2013-09-02T02:18:23.630 回答
0

示例数据更清楚:)

查询 #1:从 0 开始计数的 1 个组

SELECT m1.* FROM messages m1 JOIN (
  SELECT DISTINCT date(created) OnlyDate FROM messages
  ORDER BY OnlyDate
  LIMIT 0,1
) m2 ON date(m1.created) = OnlyDate;

|             CREATED |   MESSAGE |
|---------------------|-----------|
|  2013-08-05 9:00:00 | Hi there! |
| 2013-08-05 10:00:00 | Hi again! |

查询 #2:1 组从 1 开始计数

SELECT m1.* FROM messages m1 JOIN (
  SELECT DISTINCT date(created) OnlyDate FROM messages
  ORDER BY OnlyDate
  LIMIT 1,1
) m2 ON date(m1.created) = OnlyDate

|             CREATED |             MESSAGE |
|---------------------|---------------------|
| 2013-08-07 14:00:00 | Hi from the future! |

您只需使用 limit 子句处理组(第一个值是起始组,第二个值是它的偏移量)。该查询也应该非常有效,并且也不难阅读。

在这里拉小提琴。

于 2013-09-02T03:25:30.033 回答