[英]How can I fetch two sets of results in a single MySQL query from the same table?
我有一个 MySQL 注释表,如下所示:
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| userid | int(11) | NO | | 0 | |
| comment | char(255) | NO | | NULL | |
| content | int(11) | NO | MUL | 0 | |
| ratings | int(11) | NO | | 0 | |
| datetime | datetime | NO | | NULL | |
| ip | int(10) unsigned | NO | | NULL | |
| is_updated | tinyint(2) | NO | | 0 | |
| record_num | int(11) | NO | PRI | NULL | auto_increment |
+------------+------------------+------+-----+---------+----------------+
现在我可以使用这样的INNER JOIN
查询从这个表和另一个表中获取用户名。
我可以得到前三个评论 ORDER BY comments.ratings DESC:
SELECT comments.userid, users.username, comments.comment, comments.ratings, comments.datetime, comments.record_num , content.uploader , content.anonymous
FROM comments
LEFT JOIN users ON comments.userid = users.record_num
LEFT JOIN content ON comments.content = content.record_num
WHERE comments.content = ? ORDER BY comments.ratings DESC limit 3
和
SELECT comments.userid, users.username, comments.comment, comments.ratings, comments.datetime, comments.record_num , content.uploader , content.anonymous
FROM comments
LEFT JOIN users ON comments.userid = users.record_num
LEFT JOIN content ON comments.content = content.record_num
WHERE comments.content = ? ORDER BY comments.datetime DESC limit ?, ?
我首先尝试按评分向用户显示前三条评论,然后按 comments.datetime DESC 常规评论顺序。
现在如何将上述两个 MySQL 查询合二为一?
正如另一个答案所说 - 您可以使用union
组合结果 - 这只是意味着将两个结果连接在一起。 然而,重要的是要注意,您不能简单地将这两个查询直接union
在一起,因为它们使用order by
,因此我们需要将它们包装在外部查询中,并使用排名变量来确保我们可以重建联合按照我们想要的顺序:
select * from (
SELECT 1 as tbl,
comments.userid,
users.username,
comments.comment,
comments.ratings,
comments.datetime,
comments.record_num,
content.uploader,
content.anonymous,
@rank := @rank + 1 as rank
FROM comments
LEFT JOIN users ON comments.userid = users.record_num
LEFT JOIN content ON comments.content = content.record_num
CROSS JOIN (select @rank := 0 ) q
WHERE comments.content = ? ORDER BY comments.ratings DESC limit 3
) q1
UNION ALL
select * from (
SELECT 2 as tbl,
comments.userid,
users.username,
comments.comment,
comments.ratings,
comments.datetime,
comments.record_num,
content.uploader,
content.anonymous,
@rank := @rank + 1 as rank
FROM comments
LEFT JOIN users ON comments.userid = users.record_num
LEFT JOIN content ON comments.content = content.record_num
CROSS JOIN (select @rank := 0 ) q
WHERE comments.content = ? ORDER BY comments.datetime DESC limit ?, ?
) q2
ORDER BY tbl asc, rank asc;
union
默认情况下是distinct
,这意味着它不会重复在两个结果集中找到的行,但是也不能保证行会按照您期望的顺序返回,因此需要用自己的tbl
值标记每个表,然后order by
该字段order by
。
如果您确定不会有重复项,则可以使用union all
而不是union
来消除重复项检查
要回答您的问题,是的,您可以使用UNION
组合您的查询,但是
我首先尝试按用户的评分向用户显示前三条评论,然后按评论顺序显示常规评论。datetime DESC
如果您正在尝试实现类似于 Stack Overflow 评论功能的功能,其中最重要的评论(或带有赞成票的评论)首先显示,那么我认为单独的查询就足够了。
如果您的查询被合并,则用户需要加载所有顶部和常规评论。 此外,使用具有UNION
大查询制作或实现分页有点困难(根据我的经验,因为我仍然是编码的菜鸟)。
免责声明:这很难,但并非不可能
如果我是要解决这个问题的人,首先我的程序将加载前三个注释。 之后,有一个“显示更多评论”按钮,它将使用Ajax发布到我的服务器并将结果(常规评论)附加到显示的评论列表中。 有了这个,查询需要像你现在所拥有的那样分开。
要将彼此叠加的结果集堆叠为一组,您需要使用“UNION” - https://dev.mysql.com/doc/refman/5.0/en/union.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.