基于两列排序mysql查询
Posted
技术标签:
【中文标题】基于两列排序mysql查询【英文标题】:order mysql query based on two columns 【发布时间】:2021-09-23 18:14:41 【问题描述】:为了让我的查询更快,我根据设置为起始值的主键id
paginate
,即posts.id > $start
。
这就是我获取常规帖子的方式,即在下一个查询请求中按顺序获取 id
// start value
$start = $_GET['start'];
if ($start <= 0)
// set as first request
$offSet = "AND posts.id > $start";
else if ($start > 0)
// set as subsequent request
$offSet = "AND posts.id < $start";
// fetch posts
$posts = $db->query("SELECT posts.id, posts.likes,
posts.dislikes, posts.comments
FROM posts, users
WHERE posts.user_id=users.id
$offSet
ORDER BY posts.id DESC LIMIT 0, 15");
这是我获取最喜欢的帖子的方式
// fetch posts
$posts = $db->query("SELECT posts.id, posts.likes,
posts.dislikes, posts.comments
FROM posts, users
WHERE posts.user_id=users.id
$offSet
AND posts.likes != 0
ORDER BY posts.likes DESC LIMIT 0, 15");
问题是如果我ORDER BY likes DESC
,id
将不是连续的,因此如果我请求更多帖子,结果将重复第一组结果。
谁能帮我写一个查询来获取帖子和ORDER BY posts.likes DESC
,并且仍然允许我根据id
对查询进行分页,这样后续请求就不会逐渐变慢(因为mysql经历了所有前几行)
这是由@RickJames 提供的实现
$start = $leftoff_likes = 0;
// fetch most liked posts
$posts = $db->query("
SELECT posts.id, posts.body, posts.user_id, posts.tag, posts.date, posts.comments, posts.likes, posts.dislikes, users.name, users.image
FROM posts, users
WHERE posts.likes <= $leftoff_likes
AND ( posts.likes < $leftoff_likes OR posts.id < $start )
AND posts.user_id=users.id
ORDER BY posts.likes DESC, posts.id DESC
LIMIT 0, 15");
echo json_encode($posts);
【问题讨论】:
使用 INNER JOIN 代替逗号 你是什么意思 代替FROM a,b WHERE a.x=b.x
,使用FROM a JOIN b ON a.x=b.x
。它们具有相同的效果;后者是“现代”语法。
是的,谢谢@RickJames,效果很好!
【参考方案1】:
高效复合:
您需要一个 2 列的 ORDER BY
才能更好地进行排序。这使WHERE
子句变得复杂,尤其是当多个项目的点赞数相同时。
从最喜欢的开始:
SELECT ...
WHERE likes <= $leftoff_likes
AND ( likes < $leftoff_likes OR id < $leftoff_id )
ORDER BY likes DESC, id DESC
LIMIT 16
从最不喜欢的开始:
SELECT ...
WHERE likes >= $leftoff_likes
AND ( likes > $leftoff_likes OR id > $leftoff_id )
ORDER BY likes ASC, id ASC
LIMIT 16
在当前页面显示前 15 条结果,并从第 16 条开始设置(下次使用)$leftoff_likes 和 $leftoff_id。通过 [Next]
和 [Prev]
按钮后面的 URL 传递它们。
OFFSET
从未使用过。
如果可行,请INDEX(likes, id)
(这个小费在http://mysql.rjweb.org/doc.php/deletebig#iterating_through_a_compound_key 中被隐藏了)
杂记:
“记住你离开的地方”比使用LIMIT
和OFFSET
更好。见:http://mysql.rjweb.org/doc.php/pagination
这会带来多项更改。我建议编写两个完整的查询,而不是使用$offset
进行修补。
【讨论】:
谢谢,请您使用我上面的代码进一步解释一下。 啊,我跳过了一些东西——$start
还不够,你还需要记住$likes
。用 $likes 和 $start 替换 $Genus 和 $species。
对我来说$likes 不是变量,我应该用posts.likes 代替吗?我很难将它们关联起来。
@MaxNjoroge - 完成一页后,您有两个数字表示页面“离开”的位置——为页面提取的“最后”行的likes
和id
。这些来自SELECT
进入PHP 变量,然后进入[Next] 或[Prev] 按钮的URL,并返回PHP 毛皮使用$likes 和$id 用于下一页的SELECT
。请参阅我的分页博客。 (建议取 16 行并记住第 16 行的 likes
和 id
;这会将 '>' 更改为 '>=' 等)
谢谢@RickJames 和@Luuk,结果@RickJames 代码工作得很好。 @Luuk,它不起作用,因为我的查询嵌套在 $db->query()
中,带有间距和换行符,不起作用。但除此之外,@RickJames 代码运行良好。谢谢@Luuk 的小提琴让我看到了这个!以上是关于基于两列排序mysql查询的主要内容,如果未能解决你的问题,请参考以下文章