加入三个MySQL表并从一个表中获取最大值

时间:2014-01-19 16:18:19

标签: mysql sql join

我想加入三张桌子。

第一个是“用户”表。

+---------+--------------+---------+
|Id       |UserName      |blah     |
+---------+--------------+---------+
|1        |Amila         |blah     |
+---------+--------------+---------+
|2        |Kamal         |blah     |
+---------+--------------+---------+
|3        |Nuwan         |blah     |
+---------+--------------+---------+

第二个是“图像”表。它包含用户上传的所有图像。此外,如果Type == PI和最大ID将是用户当前的个人资料图片。

+---------+--------------+---------+---------+
|Id       |Image         |Type     |User     |
+---------+--------------+---------+---------+
|1        |12358.jpg     |PI       |1        |
+---------+--------------+---------+---------+
|2        |12589.jpg     |PI       |2        |
+---------+--------------+---------+---------+
|3        |45862.jpg     |Other    |2        |
+---------+--------------+---------+---------+
|4        |35698.jpg     |PI       |1        |
+---------+--------------+---------+---------+

第三个“评论”表包含所有评论。

+---------+--------------+---------+
|Id       |Comment       |User     |
+---------+--------------+---------+
|1        |blah blah...  |1        |
+---------+--------------+---------+
|2        |blah blah...  |1        |
+---------+--------------+---------+
|3        |blah blah...  |2        |
+---------+--------------+---------+

我想要做的是编写一个返回

的查询

Users.Id,Users.UserName,Images.Image(max Id& Type == PI),Comments.Id,Comments.Comment

基本上就是加入三张桌子。

这是我的代码

SELECT U.`Id`, U.`UserName`, I.`Image`, C.`Id`, C.`Comment` 
FROM `Users` U 
INNER JOIN `Images` I ON I.`Image` = (
    SELECT MAX(I.`Image`) FROM `Images` WHERE I.`User` = U.`Id`
) AND I.`Type` = 'PI' 
INNER JOIN `Comments` C ON C.`User` = U.`Id` 

但是这将返回Images表中的所有图像。例如,它返回用户1的两个图像。我只需要上次上传的图像。

3 个答案:

答案 0 :(得分:0)

您需要对结果进行降序排序,以便将最后一个结果排在最前面,然后将结果限制为1.这样的事情会这样做:

SELECT U.`Id`, U.`UserName`, I.`Image`, C.`Id`, C.`Comment`
FROM `Users` U
INNER JOIN `Images` I ON I.`User`=U.`Id`
INNER JOIN Comments c ON C.`User` = U.`Id`
WHERE I.`Id` IN ( SELECT MAX(`Id`) FROM `Images` GROUP BY `User` )
ORDER BY I.`Image` DESC
LIMIT 1

答案 1 :(得分:0)

这将为您提供所需的结果。在子查询上使用LEFT JOIN的目的是为每个用户名创建一条记录,即使它在表Images上没有匹配的记录也是如此。 LEFT JOIN上的子查询还有一个子查询,可以为每个image获取最新的上传user

SELECT  a.Id, 
        a.UserName, 
        c.Image, 
        b.Id, 
        b.Comment
FROM    User a
        INNER JOIN Comments b
            ON a.ID = b.User
        LEFT JOIN
        (
            SELECT  i.*
            FROM    Images i
                    INNER JOIN
                    (
                        SELECT  User, MAX(ID) ID
                        FROM    Images
                        WHERE   Type = 'PI'
                        GROUP   BY User
                    ) o ON  i.User = o.User
                            AND i.ID = o.ID
        ) c ON  a.ID = c.User

否则,如果您确定在表Images上至少有一个匹配记录,则可以在所有联接上使用INNER JOIN

SELECT  a.Id, 
        a.UserName, 
        c.Image, 
        b.Id, 
        b.Comment
FROM    User a
        INNER JOIN Comments b
            ON a.ID = b.User
        INNER JOIN  Images c
            ON a.ID = c.User
        INNER JOIN
        (
            SELECT  User, MAX(ID) ID
            FROM    Images
            WHERE   Type = 'PI'
            GROUP   BY User
        ) o ON  i.User = o.User
                AND i.ID = o.ID

答案 2 :(得分:0)

我认为这是您的目标:

SELECT U.`Id`, U.`UserName`, I.`Image`, C.`Id`, C.`Comment` 
FROM `Users` U INNER JOIN
     `Images` I
     ON I.id = (SELECT MAX(I.id)
                FROM `Images`
                WHERE `User` = U.`Id` and `Type` = 'PI'
               ) INNER JOIN 
     `Comments` C
     ON C.`User` = U.`Id` ;

我觉得这是一种编写查询的奇怪方式。我倾向于在单独的步骤中进行max()比较:

SELECT U.`Id`, U.`UserName`, I.`Image`, C.`Id`, C.`Comment` 
FROM `Users` U INNER JOIN
     `Images` I
     ON i.`User` = U.`Id` INNER JOIN
     (select user, max(I.id) as maxid
      FROM `Images`
      WHERE `Type` = 'PI'
     ) maxi
     ON i.id = maxi.maxid join
     `Comments` C
     ON C.`User` = U.`Id` ;