3

我有一个包含日历项目的表格;在我的 Web 应用程序中,我有两个视图:

  1. 视图 1:显示接下来 10 个项目的主视图,从现在开始
  2. 视图 2:根据视图 1 中第一个/最后一个项目的时间戳显示上一个/下一个 10 个项目的视图。这是麻烦制造者。

在页面底部,显示了指向视图 2 的上一个/下一个链接。

问题:

如何在不知道日期的情况下检索前一组 10 个项目?

起初,这对我来说似乎很简单,但显然事实并非如此。

数据库表:

+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| name        | varchar(255)     | YES  | MUL | NULL    |                |
| start_time  | datetime         | YES  |     | NULL    |                |
| end_time    | datetime         | YES  |     | NULL    |                |
| created     | datetime         | NO   |     | NULL    |                |
| updated     | datetime         | YES  |     | NULL    |                |
| deleted     | tinyint(1)       | NO   |     | 0       |                |
+-------------+------------------+------+-----+---------+----------------+

从现在开始显示接下来的 10 个项目的 SQL 查询(这里没有问题):

SELECT ci.*
FROM `calendar_item` AS `ci` 
WHERE ci.end_time >= NOW()
GROUP BY `ci`.`id` 
ORDER BY `ci`.`end_time` ASC
LIMIT 10

用于显示前 10 个项目的 SQL 查询,基于主视图中第一个项目的时间戳:

SELECT ci.*
FROM `calendar_item` AS `ci` 
WHERE (ci.id IN (
    SELECT id FROM calendar_item 
    WHERE (end_time < FROM_UNIXTIME(1334667600))
    ORDER BY end_time DESC
))
GROUP BY `ci`.`id` 
ORDER BY `ci`.`end_time` ASC
LIMIT 10

时间戳通过 URL 传递;在视图 1 中根本没有显示子查询。问题在于项目应该按升序排序;这将导致返回数据库中最早的项目,而不是最接近timestamp. 为了解决这个问题,我创建了一个降序排序的子查询。当我将这个子查询作为普通查询运行时,它可以正常工作,但是当包含在上述查询中时,它只显示与以下相同的结果:

SELECT ci.*
FROM `calendar_item` AS `ci` 
WHERE ci.end_time <= 1334667600
GROUP BY `ci`.`id` 
ORDER BY `ci`.`end_time` ASC
LIMIT 10

我很可能忽略了一些东西,所以我可以使用你的帮助。提前致谢。

4

1 回答 1

1

这是一个简单的,限制子查询

SELECT ci.*
FROM `calendar_item` AS `ci` 
WHERE (ci.id IN (
    SELECT id FROM calendar_item 
    WHERE (end_time < FROM_UNIXTIME(1334667600))
    ORDER BY end_time DESC
    LIMIT 10
))
GROUP BY `ci`.`id` 
ORDER BY `ci`.`end_time` ASC
LIMIT 10

如果没有子查询中的限制,您将选择时间戳 < FROM_UNIXTIMESTAMP 的所有行。然后您重新排序 ASC 并选择前 10 个,即最早的 10 个。

如果您限制子查询,您将获得满足 FROM_UNIXTIME 的最高 10 个,然后外部可以选择它们。

另一种选择(也是我的首选)如下,子查询获取数据,外部查询只是在将其吐出之前对其进行重新排序。

SELECT i.*
FROM (
    SELECT ci.*
    FROM calendar_item AS ci
    WHERE ci.end_time < FROM_UNIXTIME(1334667600)
    ORDER BY ci.end_time DESC
    LIMIT 10
) AS i
ORDER BY i.`end_time` ASC
于 2012-04-17T10:26:49.810 回答