PHP - 如果行数大于20,则限制为10个偏移量为1。

5
我正在展示数据库中最新的10个话题和最老的10个话题。我能够在最新的10个话题中展示我需要的内容。我的问题是,当数据库中有21个话题时,最后的10个话题按照我想要的方式显示,但当数据库中只有20个话题时,最新的最后一个话题仍然会出现在最老的话题中。为了更清楚,请参考以下图片。
- 当数据库中有21个或更多话题时,情况如下 - This is what happen when I have 21 or more topics in database - 当数据库中有20个话题时,情况如下 - This is what happen when I have 20 topics in database 我不希望像当有20个话题时那样重复出现某个话题。这是我从数据库中获取最后10个话题的代码:
    //  fetching last 10 topics from forum
 function history() {
    $sql = "SELECT * FROM (
    SELECT f_id AS id, f_title AS name,f_dept AS dept,f_last_view AS last_view
    FROM forum
    ORDER BY last_view ASC
    LIMIT 10 OFFSET 1
  ) AS `table` ORDER by last_view DESC ";

  //-run  the query against the mysql query function 
  $result=mysql_query($sql) or die(mysql_error());  


  $history = array();  

  //-create  while loop and loop through result set 
  while (($row = mysql_fetch_assoc($result)) !== false){
    $history[] = array(
        'id'            => $row['id'],
        'name'          => $row['name'],
        'dept'          => $row['dept'],
        'last_view'     => $row['last_view'],
    );
}

return $history;
}

提示:我知道mysql_*已经不推荐使用,但请原谅我的使用。预先感谢您的理解。


什么是问题? - Varis
2个回答

3
您的问题有点不清楚——是想要最新的10个(您已经可以工作了)和最旧的10个吗?还是最新的10个和接下来的10个?
我假设您想要最新的10个和接下来的10个。
您的问题似乎在于理解sql中的offset关键字。Offset会跳过指定数量的结果。
基于此,您当前正在按照最后一次查看(我将假设这是某种时间戳)升序排序结果——从最旧到最新,然后选择其中10个,从第二个开始。
如果您想要的是第11-20个最新的结果,请尝试
ORDER BY last_view DESC
  LIMIT 10 OFFSET 10

在你的查询范围内。

此外,参见这个stackoverflow问题,其中有一个更详细的答案。


哇!非常感谢...它按照我想要的方式工作了。谢谢您理解我的不清楚的问题。 :) ...下次我会尽力提出一个清晰的问题... - justMe

2

你的问题中提出了两个问题。第一个是你的查询存在一个简单的技术问题:

    SELECT f_id AS id, f_title AS name,f_dept AS dept,f_last_view AS last_view
    FROM forum
    ORDER BY last_view ASC
    LIMIT 10 OFFSET 1

由于您使用了OFFSET 1,将返回11个最旧的条目中除最旧的条目之外的所有条目。要获取10个最旧的条目,请使用:

SELECT f_id AS id, f_title AS name,f_dept AS dept,f_last_view AS last_view
FROM forum
ORDER BY last_view ASC
LIMIT 10

如果您想要输出接下来的10个最旧的条目(例如,如果您有100个条目并想要输出第81-90个条目),则正确使用OFFSET应该是:

SELECT f_id AS id, f_title AS name,f_dept AS dept,f_last_view AS last_view
FROM forum
ORDER BY last_view ASC
LIMIT 10 OFFSET 10

您提出的第二个问题是不希望“最老”的列表中已经输出了“最新”列表中的条目,只有在表格中总共有19个或更少的条目时才会发生这种情况(如果两个列表都有10个条目)。因此,如果您有15个条目,您希望:

最新

  • 15
  • 14
  • 13
  • 12
  • 11
  • 10
  • 9
  • 8
  • 7
  • 6

最老的列表为:

最老

  • 5
  • 4
  • 3
  • 2
  • 1

为避免重叠,您可以编写以下查询:

SELECT oldest.f_id AS id, f_title AS name,f_dept AS dept,f_last_view AS last_view
FROM forum AS oldest
LEFT JOIN (
     SELECT f_id FROM forum ORDER BY last_view DESC LIMIT 10 
) AS newest ON newest.f_id = oldest.f_id
     WHERE newest.f_id IS NULL
ORDER BY last_view ASC
LIMIT 10

这将确保过滤掉前十个条目,只留下最老的5个条目(在这个例子中是最老的列表)。
更新后使用LEFT JOIN获取并过滤掉前10个条目,因为似乎在IN和类似的比较函数中使用子查询不允许使用LIMIT。

我尝试了你的建议,但是出现了这个错误:此版本的MySQL还不支持“LIMIT&IN / ALL / ANY / SOME子查询”。 - justMe
抱歉,我重写了代码,使用LEFT JOIN来实现相同的功能。可能运行速度更快。 - Anthony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接