如何在 MySQL 数据库中创建一个简单的粘性位置文章列表,只需一次查询即可检索?

发布于 2024-08-16 09:36:20 字数 879 浏览 2 评论 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)

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

I have a paginated list of articles that needs to be sorted by rank but when an article has position <> 0 then it must be inserted in that specific position.
I thought that I can at least have the articles with the correct position extracted for the current page and then sort them in PHP to show then in the proper position.
I want to do this in MySQL with only one query

Some of my attempts are:

This query tries to select first the articles that have the correct position for the current page and then articles with the highest rank

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 is the number of articles displayed on page and 1 is the current page number, they are added on query generation.

This query has the problem that on page 2 the results are wrong because by adding LIMIT 50,50 you can go beyond the articles that have a position on that page.

Another attempt:

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)

To work correctly the second query must have a limit equal to the number of rows returned from the first query.
Plus, anytime an article that has a very high rank that but also a very high position it will be shown earlier because position is ignored in the second query.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

安稳善良 2024-08-23 09:36:20

您的第一个 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

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

Your first ORDER BY expression isn't needlessly complex enough. Try:

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

Alternately, just use:

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

I recommend complexifying (or, if you must, simplifying) the rest of your expressions as well. I predict you'll either find your problem, or open a hole into another universe, wherein the magical unicorns will solve your problem.

ぽ尐不点ル 2024-08-23 09:36:20

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

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

yeah, the magic unicorn is right, that query is wrong
here is the real magic query

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
柠栀 2024-08-23 09:36:20

我找到了问题的答案。
我放弃了 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

I found the answer to the question.
I gave up on the sql + php sorting solution and found a full sql solution where I get all articles sorted by rank and position where available.

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
烟织青萝梦 2024-08-23 09:36:20

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

one minor observation a magic unicorn could see in the last query - you're ordering the result set on a field (loc) that is based on another field (@rownum) which you expect to have values based on the sorted set. Mystical? Circular dependencies? Or just strange? ;-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文