查询以从多个表MySQL中进行选择



我有两个表。我的任务是选择最后一个人的评论。

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在运行这个查询时应该能够处理(非常(大的表。。

参见演示

最新更新