MySQL关联查询排序问题:按Protein值降序排列结果
解决方案
要实现按Protein的value值从高到低排序,你需要先在分组时提取出每个产品对应的Protein数值,再基于这个数值进行排序。修改后的查询语句如下:
SELECT `product`.`name` AS `name`, JSON_ARRAYAGG(JSON_OBJECT('name', `ingredient`.`permalink`, 'value', `_related_product_ingredient`.`value` )) AS `ingredients`, -- 提取当前产品的Protein值,若不存在则设为0 COALESCE(MAX(CASE WHEN `ingredient`.`permalink` = 'Protein' THEN `_related_product_ingredient`.`value` END), 0) AS `protein_value` FROM `_related_product_ingredient` INNER JOIN `product` ON `product`.`id` = `_related_product_ingredient`.`product_id` INNER JOIN `ingredient` ON `ingredient`.`id` = `_related_product_ingredient`.`ingredient_id` GROUP BY `_related_product_ingredient`.`product_id`, `product`.`name` -- 按Protein值降序排序 ORDER BY `protein_value` DESC;
关键说明:
- 用
CASE WHEN配合MAX()函数,在分组时筛选出当前产品对应Protein配料的value值(每个产品仅对应一条Protein记录,MAX()仅用于聚合单个值,用SUM()效果一致)。 COALESCE()函数处理无Protein配料的产品,将其Protein值设为0,避免NULL值在排序时排在最前。- 分组字段添加
product.name,符合MySQL的ONLY_FULL_GROUP_BY模式要求,避免分组与查询字段不匹配的报错。
如果不需要在结果中显示protein_value字段,可改用子查询实现:
SELECT `name`, `ingredients` FROM ( SELECT `product`.`name` AS `name`, JSON_ARRAYAGG(JSON_OBJECT('name', `ingredient`.`permalink`, 'value', `_related_product_ingredient`.`value` )) AS `ingredients`, COALESCE(MAX(CASE WHEN `ingredient`.`permalink` = 'Protein' THEN `_related_product_ingredient`.`value` END), 0) AS `protein_value` FROM `_related_product_ingredient` INNER JOIN `product` ON `product`.`id` = `_related_product_ingredient`.`product_id` INNER JOIN `ingredient` ON `ingredient`.`id` = `_related_product_ingredient`.`ingredient_id` GROUP BY `_related_product_ingredient`.`product_id`, `product`.`name` ) AS product_with_protein ORDER BY `protein_value` DESC;
内容的提问来源于stack exchange,提问作者Kamil
相关产品推荐
相关产品推荐

