Mysql ONLY_FULL_GROUP_BY 模式问题 - 为每个相册选择单个图像 URL(任意)

Sud*_*Pal 1 mysql database query-optimization

我需要有关 mysql 查询的帮助,以下是详细信息:

三张表,相册_大师,相册_照片_地图,照片_详细信息

相册_主表结构

album_id(P) | album_name | user_id(F)
1               abc           1
2               xyz           1
3               pqr           1
4               e3e           2
Run Code Online (Sandbox Code Playgroud)

相册_照片_地图表结构

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
Run Code Online (Sandbox Code Playgroud)

Photo_Details 表结构

auto_id(P) | image_id(F) | image_url
1               123          http....
2               124          http....
3               125          http...
Run Code Online (Sandbox Code Playgroud)

我想编写一个查询来获取带有 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)
Run Code Online (Sandbox Code Playgroud)

我使用的查询花费了太多时间来执行,将近 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;
Run Code Online (Sandbox Code Playgroud)

我正在寻找查询的优化版本,任何帮助将不胜感激。如果我image_url在 group by 它创建多个记录,如果我删除D.image_url它也会给我错误

D.image_url' 在功能上不依赖于 GROUP BY 子句中的列;这与 sql_mode=only_full_group_by 不兼容

注意:用户可以在多个相册中分配一张照片,结果每个相册只能选择一张照片,一个相册中可能有 100 张照片。

Jit*_*dav 5

如果它应该包含在结果集中的哪个 url 无关紧要,那么您可以只进行 group byalbum_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;
Run Code Online (Sandbox Code Playgroud)

注意:如果您想要相册信息,即使没有附加照片,请使用LEFT JOIN而不是INNER JOIN查询。

由于 ONLY_FULL_GROUP_BY 导致的功能依赖问题

MySQL 5.7.5 及更高版本实现了功能依赖检测。如果启用了 ONLY_FULL_GROUP_BY SQL 模式(默认情况下是这样),MySQL 将拒绝选择列表、HAVING 条件或 ORDER BY 列表引用非聚合列的查询,这些列既不在 GROUP BY 子句中命名,也不在功能上依赖它们

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

解决方案 1: 如果可能aggregate,请对未包含在group by子句中的其他列使用函数。

解决方案 2: 如果您知道,对于给定的数据集,每个album_id值实际上唯一地确定了image_url意味着image_url在功能上有效依赖于 的值album_id。所以你可以做

SELECT 
    A.album_id, A.album_name, ANY_VALUE(D.image_url) AS 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;
Run Code Online (Sandbox Code Playgroud)

解决方案 3:或者only_full_group_by在 mysql 中禁用

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

SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
Run Code Online (Sandbox Code Playgroud)

更多信息检查 Solve Query Failures Regarding ONLY_FULL_GROUP_BY SQL MODE