0

我有一个需要按排名排序的文章的分页列表,但是当文章的位置 <> 0 时,它必须插入到该特定位置。我认为我至少可以为当前页面提取具有正确位置的文章,然后在 PHP 中对它们进行排序以显示在正确的位置。我想在 MySQL 中只用一个查询来做到这一点

我的一些尝试是:

此查询首先尝试选择当前页面位置正确的文章,然后选择排名最高的文章

SELECT id, rank_score, position
FROM Articles
ORDER BY ((position <= (50 * 1)) AND (position > 50 * (1-1))) DESC, rank_score DESC
LIMIT 0, 50

50 是页面上显示的文章数,1 是当前页码,它们是在查询生成时添加的。

这个查询的问题是在第 2 页上的结果是错误的,因为通过添加 LIMIT 50,50 您可以超越在该页面上具有位置的文章。

另一种尝试:

SELECT (
    SELECT id, rank_score, position
      FROM Articles
  ORDER BY ((position <= (50 * 1)) AND (position > 50 * (1-1))) DESC, rank_score DESC  
     LIMIT 50)
UNION (
  SELECT id, rank_score, position
    FROM Articles
 ORDER BY rank_score DESC LIMIT x)

要正常工作,第二个查询的限制必须等于从第一个查询返回的行数。另外,任何时候一篇文章的排名很高,但位置也很高,因为在第二个查询中忽略了位置,所以它会更早地显示。

4

4 回答 4

11

您的第一个 ORDER BY 表达式不够复杂。尝试:

ORDER BY ((position < (50 * (1 + (1-1 * (50 / 1)))) 
    OR position = (50 + (50 - (50 * POW(50, 0)) * 1))) 
  AND (position > 50 * (1-1) / 1 * 50)) DESC

或者,只需使用:

ORDER BY (position <= 50 AND position > 0) DESC

我建议将其余的表达式也复杂化(或者,如果必须的话,简化)。我预测你要么找到你的问题,要么打开一个通往另一个宇宙的洞,在那里神奇的独角兽会解决你的问题。

于 2009-12-21T17:49:19.790 回答
1

是的,神奇的独角兽是对的,这个查询是错误的,这是真正的神奇查询

SELECT * FROM (
SELECT @rownum:=@rownum+1 rownum, IF(position=0,@rownum,position) as loc, a.id, a.rank_score, a.position
FROM (SELECT @rownum:=0) r, Articles a
ORDER BY rank_score DESC) t 
ORDER BY loc DESC
LIMIT 0, 50
于 2009-12-22T11:37:15.767 回答
0

一个神奇的独角兽可以在最后一个查询中看到的一个小观察 - 您正在对基于另一个字段 (@rownum) 的字段 (loc) 上的结果集进行排序,您希望该字段具有基于排序集的值。神秘?循环依赖?还是只是奇怪?;-)

于 2009-12-22T10:17:31.740 回答
0

我找到了问题的答案。我放弃了 sql + php 排序解决方案,并找到了一个完整的 sql 解决方案,在该解决方案中,我可以在可用的情况下按排名和位置对所有文章进行排序。

SELECT @rownum:=@rownum+1 rownum, IF(position=0,@rownum,position) as loc, a.id, a.rank_score, a.position
FROM (SELECT @rownum:=0) r, Articles a
ORDER BY  loc, rank_score DESC
LIMIT 0, 50
于 2009-12-22T09:39:01.350 回答