我有两个表。我的任务是选择最后一个人的评论。
db_user(db_user_id,名称,余额(
db_comment(db_comment_id,db_user_id,text(
我的查询:
SELECT db_user.name,db_comment.text
FROM db_user INNER JOIN db_comment ON db_user.db_user_id = db_comment.db_user_id
ORDER BY db_comment.db_user_id DESC
尝试使用LIMIT
,但失败。
包含值的表已在此处创建:http://sqlfiddle.com/#!2014年9月9日
我的数据采样应该收到每个人(db_user.name
(的最后一条评论(db comment.text
(。
条件下,不能添加新字段。
您可以使用额外的JOIN
:使用以下解决方案
SELECT dbu.name, dbc.text
FROM db_user dbu INNER JOIN (
SELECT MAX(db_comment_id) AS db_comment_id, db_user_id
FROM db_comment
GROUP BY db_user_id
) dbc_max ON dbu.db_user_id = dbc_max.db_user_id
INNER JOIN db_comment dbc ON dbu.db_user_id = dbc_max.db_user_id
AND dbc.db_comment_id = dbc_max.db_comment_id
ORDER BY dbu.db_user_id DESC
或者直接在SELECT
:上使用子选择
SELECT dbu.name, (
SELECT `text`
FROM db_comment dbc
WHERE dbu.db_user_id = dbc.db_user_id
ORDER BY dbc.db_comment_id DESC
LIMIT 1
) AS `text`
FROM db_user dbu
ORDER BY dbu.db_user_id DESC
dbfiddle.uk上的演示
我会使用相关的子查询进行筛选。在许多情况下,这是性能最好的方法,尤其是在db_comment(db_user_id, db_comment_id)
:上有索引的情况下
select u.name, c.text
from
db_user u
inner join db_comment c on c.db_user_id = u.db_user_id
where c.db_comment_id = (
select max(c1.db_comment_id)
from db_comment c1
where c1.db_user_id = c.db_user_id
)
这假设最后一个注释是具有最高db_comment_id
的注释。
DB Fiddle上的更新演示
name text
Ivan Message3 ivan
Petr Message3 Petr
Artur Message2 Artur
John Message2 John
最后一条注释是ID最高的注释。因此,请确保用户不存在更高的注释:
SELECT
u.name,
c.text
FROM db_user u
JOIN db_comment c ON c.db_user_id = u.db_user_id
AND NOT EXISTS
(
SELECT *
FROM db_comment c2
WHERE c2.db_user_id = c.db_user_id
AND c2.db_comment_id > c.db_comment_id
);
或者使用每个用户的最高评论ID列表:
SELECT
u.name,
c.text
FROM db_user u
JOIN db_comment c ON c.db_user_id = u.db_user_id
AND (c.db_user_id, c.db_comment_id) IN
(
SELECT db_user_id, MAX(db_comment_id)
FROM db_comment
GROUP BY db_user_id
);
从MySQL 8开始,您还可以使用窗口功能。例如:
SELECT
u.name,
c.text
FROM db_user u
JOIN
(
SELECT
db_user_id,
text,
ROW_NUMBER() OVER (PARTITION BY db_user_id ORDER BY db_comment_id DESC) AS rn
FROM db_comment
) c ON c.db_user_id = u.db_user_id AND c.rn = 1;
演示:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=2c2c67cdba80a992b593e4c74201fa61
试试看-
SELECT db_user.name,db_comment.text
FROM db_user
INNER JOIN db_comment
ON db_user.db_user_id = db_comment.db_user_id
ORDER BY db_user.db_user_id DESC, db_comment.db_comment_id desc
limit 1
或
SELECT db_user.name,db_comment.text
FROM db_user
JOIN (
select db_comment_id as maxId, db_user_id, text
from db_comment
order by db_comment_id desc
limit 1
) as db_comment ON db_comment.db_user_id = db_user.db_user_id
ORDER BY db_user.db_user_id DESC`
如果限制不起作用,则可以使用MAX函数并使联接自表
无需使用MAX(db_comment_id)
或GROUP BY db_user_id
并通过过滤完成的其他方法
查询
SELECT
db_user.name
, db_comment1.text
FROM
db_comment db_comment1
LEFT JOIN
db_comment db_comment2
ON
db_comment1.db_user_id = db_comment2.db_user_id
AND
db_comment1.db_comment_id < db_comment2.db_comment_id
INNER JOIN
db_user
ON
db_comment1.db_user_id = db_user.db_user_id
WHERE
db_comment2.db_user_id IS NULL
注意:使用db_comment1.db_comment_id > db_comment2.db_comment_id
将执行MIN(db_comment_id)
是的,运算符方向可能会有点违反直觉,而且很容易出错并写错(这就是为什么我需要编辑我的答案…(,请参阅演示。。
结果
| name | text |
|-------|----------------|
| Ivan | Message3 ivan |
| Petr | Message3 Petr |
| Artur | Message2 Artur |
| John | Message2 John |
性能说明:它需要在db_comment
表上有INDEX(db_user_id, db_comment_id)
,否则速度不会很快。如果你有这个索引,MySQL在运行这个查询时应该能够处理(非常(大的表。。
参见演示