查询以从多个表中选择MySQL

我有两个桌子。我的任务是选择最后一位评论。

  

db_user (db_user_id,名称,余额)

     

db_comment (db_comment_id,db_user_id,文本)

我的查询:

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/#!9/badaf/14

我的数据采样应收到每个人(db comment.text)的最后评论(db_user.name)。

此外,您不能添加新字段。

BlueChiang 回答:查询以从多个表中选择MySQL

您可以通过附加的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

demo on dbfiddle.uk

,

最后一条评论是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

,

我将使用相关子查询进行过滤。在许多情况下,这是性能最佳的方法,尤其是在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
)

这假定 last 注释是db_comment_id最高的注释。

Updated demo on DB Fiddle

name    text
Ivan    Message3 ivan
Petr    Message3 Petr
Artur   Message2 Artur
John    Message2 John
,

尝试-

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

OR

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_idMIN(db_comment_id)是的,操作员的方向可能会感觉有点违反直觉,而且很容易出错并写错了方向(即为什么我需要编辑我的答案...),请参见demo

结果

|  name |           text |
|-------|----------------|
|  Ivan |  Message3 ivan |
|  Petr |  Message3 Petr |
| Artur | Message2 Artur |
|  John |  Message2 John |

性能说明:它需要在INDEX(db_user_id,db_comment_id)表上有db_comment,否则不会很快。如果您有该索引,则在运行此查询时,MySQL应该能够处理(非常大的)表。

请参阅demo

本文链接:https://www.f2er.com/3110909.html

大家都在问