Mysql-使用与相册映射的单个图像URL检索相册详细信息

时间:2019-08-24 17:30:54

标签: mysql database query-optimization

我在mysql查询中需要帮助,这是详细信息:

三张桌子Album_Master,Album_Photo_Map和Photo_Details

相册主表结构

album_id(P) | album_name | user_id(F)
1               abc           1
2               xyz           1
3               pqr           1
4               e3e           2

相册照片地图表结构

auto_id(P) | album_id(F) | photo_id
1             1              123
2             1              124
3             2              123 
4             2              125
5             1              127
6             3              127

Photo_Details表结构

auto_id(P) | image_id(F) | image_url
1               123          http....
2               124          http....
3               125          http...

我想编写一个查询以获取带有user_id 1的图像URL的相册名称 我期望的输出是

album_id | album_name | image_url
1            abc          http.. (either 123 or 124 or 127 - only one url)
2            xyz          http.. (either 123 or 125 - only one)
3            pqr          http.. (127 only)

我正在使用的查询执行时间过多,将近8秒钟。

SELECT A.album_id
     , A.album_name
     , D.image_url 
  from Album_Master A
     , Album_Photo_Map E 
  LEFT 
  JOIN Photo_Details D 
    ON (D.image_id = (
      SELECT P.photo_id 
        FROM Album_Photo_Map P
           , Photo_Details Q 
       WHERE P.photo_id = Q.image_id 
         AND P.album_id = E.album_id limit 0,1)
       ) 
 WHERE A.album_id = E.album_id 
   AND A.user_id = 1 
 group 
    by A.album_id
     , E.album_id
     , D.image_url;

我正在寻找查询的优化版本,对您的帮助将不胜感激。 注意:用户可以在多个相册中分配一张照片,结果每个相册只能选择一张照片,一个相册中可能有100张照片。

1 个答案:

答案 0 :(得分:4)

如果要在结果集中包含哪个url都没有关系,那么您只可以按album_id进行分组,就可以了。

SELECT 
    A.album_id, A.album_name, D.image_url 
FROM album_master A
INNER JOIN album_photo_map P ON A.album_id = P.album_id
INNER JOIN photo_details D ON P.photo_id = D.image_id
GROUP BY A.album_id;

注意:如果您甚至想要相册信息也没有照片,请在查询中使用LEFT JOIN而不是INNER JOIN

特定问题:D.image_url”在功能上不依赖于GROUP BY子句中的列;这与sql_mode = only_full_group_by

不兼容

在mysql中禁用only_full_group_by

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));