简体   繁体   中英

Using MAX in GROUP_CONCAT

I have a problem related to the Invalid use of group function in MySQL.

The query I'm trying to execute is this (and I know that is a very huge query, but if I can execute this, then I'll adjust and fix for performance and easy reading stuff):

SELECT
    `id_c` AS `sceneId`,
    `scene`.`id` AS `sceneName`,
    `scene`.`frameCount` AS `frames`,
    task.id_mv AS `id_mv`,
    CONCAT( '[',GROUP_CONCAT(
        CONCAT( 
            '{',
                '"idTk": ', `task`.`id_tk`, ', ',
                -- '"tktype": ', `task`.`id_tk_type`, ', ',
                -- '"subDepType": ', IF ( `task`.`id_sub_dep_type` = 54, `task`.`id_sub_dep_type`, 'null'), ', ',
                -- '"color": "', `task`.`color`, '", ',
                '"weight": ', MAX(`task`.`weight`), ', ',
                '"dept": ', '"',
                    CASE `task`.`id_tk_type`
                        WHEN 43 THEN 'MVB'
                        WHEN 12 THEN 'LYT'
                        WHEN 32 THEN
                            CONCAT_WS(
                                ', ',
                                IF( `task`.`id_sub_dep_type` != 54, 'ANI', NULL ),
                                IF( `task`.`id_sub_dep_type` = 54, 'CKD', NULL )
                            )
                        WHEN 190 THEN 'DYN'
                        WHEN 104 THEN 'FIN'
                        WHEN 191 THEN 'LGT'
                    END, '"',
                -- task.id_tk_type, ', ',
                -- task.id_sub_dep_type,            
            '}'
        )
        ORDER BY
            FIELD( `task`.`id_tk_type`, 43, 12, 32, 190, 104, 191 ),
            `task`.`weight` DESC
        SEPARATOR
            ', '
    ), ']') AS `tkInfo`
FROM
        `V_task` AS `task`
        JOIN `tk_fct_mcsc` AS `mcsc` ON `task`.`id_tk` = `mcsc`.`id_tk`
        JOIN `scene` ON `mcsc`.`id_c` = `scene`.`id_scene`
WHERE
    `task`.`id_sub_dep_type` IN (
        SELECT
            `id_sub_dep_type`
        FROM
            `tk_dim_sub_dep_type`
        WHERE `id_tk_type` IN (
            SELECT
                `id_tk_type`
            FROM
                `tk_dim_dep_type`
            WHERE
                `id_tk_type` IN ( 43, 12, 32, 190, 104, 191 )
        )
              AND `id_sub_dep_type` != 54
        UNION
        SELECT
            `id_sub_dep_type`
        FROM
            `tk_dim_sub_dep_type`
        WHERE
            `id_sub_dep_type` = 54
    )
    AND `task`.`is_appr` = FALSE
    AND `mcsc`.`type` = 'sc'
    AND `scene`.`id` != '000'
    -- AND `mcsc`.`id_b` = 530
GROUP BY
    `scene`.`id`,
    `scene`.`id_scene`
    -- task.weight
ORDER BY
    `scene`.`id`,
    `task`.`weight` DESC;

The error, I know is the MAX( task.weight ) inside the GROUP_CONCAT function, but I don't know how to avoid this thing..

I'm actually trying to build some sort of sqlfiddle thing to let you test this stuff, but what I need I think is just another pairs of eye that let me know where to see.

Thanks!

EDIT # 1 As kickstart asked, what I whant to obtain is something like that:

sceneId sceneName   frames  id_mv   tkInfo
200     001         1200    1       "[{"dept": "LGT"}, {"dept": "LGT"}]"
1342    001         45      14      "[{"dept": "LYT"}, {"dept": "LGT"}, {"dept": "LGT"}]"
1335    001         460     14      "[{"dept": "MVB"}, {"dept": "LYT"}, {"dept": "LGT"}, {"dept": "LGT"}]"
1351    001         20      11      "[{"dept": "LYT"}, {"dept": "ANI"}, {"dept": "FIN"}, {"dept": "LGT"}]"
1375    001         63      11      "[{"dept": "LYT"}, {"dept": "CKD"}, {"dept": "ANI"}, {"dept": "DYN"}, {"dept": "FIN"}, {"dept": "FIN"}, {"dept": "FIN"}, {"dept": "LGT"}]"
1382    001         66      11      "[{"dept": "LYT"}, {"dept": "CKD"}, {"dept": "ANI"}, {"dept": "FIN"}]"

But, without the repetition for the "dept", and to do so, i need the MAX weight fot that dept.

EDIT # 2 I have solved this problem of mine with a little cheat.

First, i have simplified a lot the main query, deleted the case-thing and inserted a MAX(weight) for each sceneId.

The, with this simplified query I have built a View, and with that view I have applied the case/group_concat thing.. and all the results are just fine.

[ ..sqlfiddle will be inserted in no time HERE.. ]

Having a bit of a play, and (very) untested, but think you would need to effectively do the query twice. Once to get the details and once to get the max weight. You could move some of your sub selects around (doing a join - the union will take care of duplicates before the join).

Something like this:-

SELECT
    Sub1.id_c AS sceneId,
    Sub1.id AS sceneName,
    Sub1.frameCount AS frames,
    Sub1.id_mv AS id_mv,
    CONCAT( '[',GROUP_CONCAT(
        CONCAT( 
            '{',
                '"idTk": ', Sub1.id_tk, ', ',
                '"weight": ', Sub2.MaxTaskWeight, ', ',
                '"dept": ', '"', Sub1.id_tk_type_decode, '"',
            '}'
        )
        ORDER BY
            FIELD( Sub1.id_tk_type, 43, 12, 32, 190, 104, 191 ),
            Sub2.MaxTaskWeight DESC
        SEPARATOR
            ', '
    ), ']') AS tkInfo
FROM
(
    SELECT
        id_c AS sceneId,
        scene.id AS sceneName,
        scene.frameCount AS frames,
        task.id_mv AS id_mv,
        task.id_tk, 
        CASE task.id_tk_type
            WHEN 43 THEN 'MVB'
            WHEN 12 THEN 'LYT'
            WHEN 32 THEN IF( task.id_sub_dep_type = 54, 'CKD', 'ANI' )
            WHEN 190 THEN 'DYN'
            WHEN 104 THEN 'FIN'
            WHEN 191 THEN 'LGT'
        END AS id_tk_type_decode,
        task.id_tk_type
    FROM    V_task AS task
    INNER JOIN  tk_fct_mcsc AS mcsc ON task.id_tk = mcsc.id_tk
    INNER JOIN  scene ON mcsc.id_c = scene.id_scene
    INNER JOIN 
    (   
        SELECT id_sub_dep_type
        FROM tk_dim_sub_dep_type 
        INNER JOIN tk_dim_dep_type
        ON tk_dim_sub_dep_type.id_tk_type = tk_dim_dep_type.id_tk_type
        WHERE  tk_dim_dep_type.id_tk_type  IN ( 43, 12, 32, 190, 104, 191 )
        AND tk_dim_sub_dep_type.id_sub_dep_type != 54
        UNION
        SELECT id_sub_dep_type
        FROM tk_dim_sub_dep_type 
        WHERE id_sub_dep_type = 54
    ) Sub1
    ON task.id_sub_dep_type = Sub1.id_sub_dep_type
    WHERE task.is_appr = FALSE
    AND mcsc.`type` = 'sc'
    AND scene.`id` != '000'
)
INNER JOIN
(
    SELECT scene.id, scene.id_scene, MAX(task.weight) AS MaxTaskWeight
    FROM    V_task AS task
    INNER JOIN  tk_fct_mcsc AS mcsc ON task.id_tk = mcsc.id_tk
    INNER JOIN  scene ON mcsc.id_c = scene.id_scene
    INNER JOIN 
    (   
        SELECT id_sub_dep_type
        FROM tk_dim_sub_dep_type 
        INNER JOIN tk_dim_dep_type
        ON tk_dim_sub_dep_type.id_tk_type = tk_dim_dep_type.id_tk_type
        WHERE  tk_dim_dep_type.id_tk_type  IN ( 43, 12, 32, 190, 104, 191 )
        AND tk_dim_sub_dep_type.id_sub_dep_type != 54
        UNION
        SELECT id_sub_dep_type
        FROM tk_dim_sub_dep_type 
        WHERE id_sub_dep_type = 54
    ) Sub1
    ON task.id_sub_dep_type = Sub1.id_sub_dep_type
    WHERE task.is_appr = FALSE
    AND mcsc.`type` = 'sc'
    AND scene.`id` != '000'
    GROUP BY scene.id, scene.id_scene 
) Sub2
ON Sub1.id = Sub2.id
AND Sub1.id_scene = Sub2.id_scene
GROUP BY
    Sub1.id,
    Sub1.id_scene
ORDER BY
    Sub1.id,
    MaxTaskWeight DESC;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM