Mysql ONLY_FULL_GROUP_BY mode issue - Pick single Image URL(any) for each Album

后端 未结 1 1299
抹茶落季
抹茶落季 2021-01-25 18:49

I need help in a mysql query, here are the details:

Three Tables, Album_Master , Album_Photo_Map, Photo_Details

Album_Master Table Structure

album_i         


        
相关标签:
1条回答
  • 2021-01-25 19:22

    If it doesn't matter which url it should include in resultset then you can just do group by album_id only and you are good to go.

    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;
    

    Note: If you want album info even there is no photo attached to it then use LEFT JOIN instead of INNER JOIN in query.

    Functional Dependency Issue due to ONLY_FULL_GROUP_BY

    MySQL 5.7.5 and later implements detection of functional dependence. If the ONLY_FULL_GROUP_BY SQL mode is enabled (which it is by default), MySQL rejects queries for which the select list, HAVING condition, or ORDER BY list refer to nonaggregated columns that are neither named in the GROUP BY clause nor are functionally dependent on them

    Specific Issue: D.image_url' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

    Solution 1: If possible use aggregate function for the other columns which are not included in group by clause.

    Solution 2: If you know that, for a given data set, each album_id value in fact uniquely determines the image_url value that means image_url is effectively functionally dependent on album_id. So you can do

    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;
    

    Solution 3: Alternatively Disable only_full_group_by in 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',''));
    

    A more info check Solve Query Failures Regarding ONLY_FULL_GROUP_BY SQL MODE

    0 讨论(0)
提交回复
热议问题