使用JOIN MySQL从多个图像中选择第一个图像

时间:2018-11-18 08:16:58

标签: php mysql sql database mysqli

我有三个表foodfav_foodfood_imagefood表包含有关食物的详细信息,food_image具有针对单个食物的多个图像,并且 fav_food表具有用户喜欢的食物ID。

food:
f_id   |  description  

food_image
f_id   |   img_url  | rank

fav_food
user_id  |  f_id

这是我尝试过的:

SELECT food.f_id, 
       food.description, 
       img.minimgrank, 
       i.img_url AS profile_photo 
FROM   fav_food 
       INNER JOIN food 
               ON fav_food.f_id = food.f_id 
       LEFT OUTER JOIN(SELECT f_id, 
                              Min(rank) AS minImgRank 
                       FROM   food_image 
                       GROUP  BY f_id) img 
                    ON img.f_id = food.f_id 
       JOIN food_image i 
         ON i.rank = img.minimgrank 
WHERE  fav_food.user_id = ? 

现在,我需要一个查询,该查询将以描述和图像显示用户最喜欢的食物。尽管有多张图像,但我需要选择一个具有最小等级的图像(假设等级为1,2,3,将选择等级为1的图像)。所以我的问题是如何编写更快的查询以实现我的目标?

2 个答案:

答案 0 :(得分:1)

考虑联接三个表,然后再使用诸如min(rank)之类的窗口函数来获取结果。

select * 
from (
       select a.user_id
              ,b.img_url
              ,b.rank
              ,min(b.rank) over(order by b.rank asc) as rnk
       from fav_food a 
       join food_image b
       on a.f_id=b.f_id
       join food c
       on a.f_id=c.f_id
     )x 
where x.rank=x.rnk

答案 1 :(得分:0)

在这种情况下,相关子查询应具有更好的性能:

SELECT f.f_id, f.description, 
       fi.rank, fi.img_url AS profile_photo 
FROM fav_food ff JOIN
     food f
     ON ff.f_id = f.f_id LEFT JOIN
     food_image fi 
     ON fi.f_id = f.f_id AND
        fi.rank = (SELECT MIN(fi2.rank) FROM food_image fi2 WHERE fi2.f_id = fi.f_id)
WHERE ff.user_id = ? ;

为了提高性能,您要确保在food_image(f_id, rank)fav_food(user_id, f_id)上都有索引,并在主键上都有索引。

为什么它比GROUP BY版本更快?首先,索引可以用于相关查询,但可能不会用于JOIN之后的GROUP BY

第二,GROUP BY需要处理图像表中的所有数据。只需处理给定用户喜欢的食物即可。

最后,在MySQL 8+中,ROW_NUMBER()是一个选项。但是,这仍然可能比该解决方案快或快(根据我对其他数据库的经验)。