You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL中如何用GREATEST对SUM别名字段进行排序?

MySQL按SUM别名字段最大值排序的解决方案

问题描述

我有一个在线彩票系统的MySQL查询,当前排序逻辑是:

ORDER BY total_numbers_line_1 DESC, total_numbers_line_2 DESC, total_numbers_line_3 DESC

我需要改成按这三个字段的最大值排序,期望写法是:

ORDER BY GREATEST(total_numbers_line_1, total_numbers_line_2, total_numbers_line_3);

但因为这三个字段是SUM子句的别名,MySQL不支持直接在ORDER BY中用GREATEST引用别名,试过GREATEST、IF、CASE WHEN都没解决,求可行方法。

我的实际查询语句:

SELECT *,
  SUM(IF(FIND_IN_SET('21', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line1), 1 ,0)
  ) AS total_numbers_line_1,
  SUM(IF(FIND_IN_SET('21', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line2), 1 ,0)
  ) AS total_numbers_line_2,
  SUM(IF(FIND_IN_SET('21', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line3), 1 ,0)
  ) AS total_numbers_line_3
FROM cards
WHERE id_bingo = '64e3da663a617'
GROUP BY
    id_card
HAVING
    total_numbers_line_1 > 0
    OR total_numbers_line_2 > 0
    OR total_numbers_line_3 > 0 
ORDER BY total_numbers_line_1 DESC,
  total_numbers_line_2 DESC,
  total_numbers_line_3 DESC
LIMIT 20

可行解决方案

方案1:子查询/CTE包裹(推荐)

把原查询的结果作为临时表,在外层使用GREATEST函数直接引用别名排序,绕开MySQL不能在ORDER BY中用函数引用SELECT别名的限制:

子查询写法(兼容所有MySQL版本)

SELECT *
FROM (
  SELECT *,
    SUM(IF(FIND_IN_SET('21', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('15', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('43', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('42', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('78', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('4', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('27', numbers_line1), 1 ,0)
    ) AS total_numbers_line_1,
    SUM(IF(FIND_IN_SET('21', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('15', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('43', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('42', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('78', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('4', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('27', numbers_line2), 1 ,0)
    ) AS total_numbers_line_2,
    SUM(IF(FIND_IN_SET('21', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('15', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('43', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('42', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('78', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('4', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('27', numbers_line3), 1 ,0)
    ) AS total_numbers_line_3
  FROM cards
  WHERE id_bingo = '64e3da663a617'
  GROUP BY id_card
  HAVING total_numbers_line_1 > 0 OR total_numbers_line_2 > 0 OR total_numbers_line_3 > 0
) AS temp_table
ORDER BY GREATEST(total_numbers_line_1, total_numbers_line_2, total_numbers_line_3) DESC
LIMIT 20

CTE写法(MySQL 8.0及以上版本支持)

用WITH子句创建临时结果集,写法更清晰:

WITH temp_table AS (
  SELECT *,
    SUM(IF(FIND_IN_SET('21', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('15', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('43', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('42', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('78', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('4', numbers_line1), 1 ,0) +
      IF(FIND_IN_SET('27', numbers_line1), 1 ,0)
    ) AS total_numbers_line_1,
    SUM(IF(FIND_IN_SET('21', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('15', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('43', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('42', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('78', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('4', numbers_line2), 1 ,0) +
      IF(FIND_IN_SET('27', numbers_line2), 1 ,0)
    ) AS total_numbers_line_2,
    SUM(IF(FIND_IN_SET('21', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('15', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('43', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('42', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('78', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('4', numbers_line3), 1 ,0) +
      IF(FIND_IN_SET('27', numbers_line3), 1 ,0)
    ) AS total_numbers_line_3
  FROM cards
  WHERE id_bingo = '64e3da663a617'
  GROUP BY id_card
  HAVING total_numbers_line_1 > 0 OR total_numbers_line_2 > 0 OR total_numbers_line_3 > 0
)
SELECT *
FROM temp_table
ORDER BY GREATEST(total_numbers_line_1, total_numbers_line_2, total_numbers_line_3) DESC
LIMIT 20

方案2:在ORDER BY中重复计算逻辑

直接把每个total_numbers_line的SUM计算逻辑放到GREATEST函数里,代码冗余但不需要修改查询结构:

SELECT *,
  SUM(IF(FIND_IN_SET('21', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line1), 1 ,0)
  ) AS total_numbers_line_1,
  SUM(IF(FIND_IN_SET('21', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line2), 1 ,0)
  ) AS total_numbers_line_2,
  SUM(IF(FIND_IN_SET('21', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line3), 1 ,0)
  ) AS total_numbers_line_3
FROM cards
WHERE id_bingo = '64e3da663a617'
GROUP BY id_card
HAVING total_numbers_line_1 > 0 OR total_numbers_line_2 > 0 OR total_numbers_line_3 > 0 
ORDER BY GREATEST(
  SUM(IF(FIND_IN_SET('21', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line1), 1 ,0)
  ),
  SUM(IF(FIND_IN_SET('21', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line2), 1 ,0)
  ),
  SUM(IF(FIND_IN_SET('21', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line3), 1 ,0)
  )
) DESC
LIMIT 20

方案3:用CASE WHEN手动实现最大值判断

如果不想用子查询或重复计算,可以在ORDER BY里用CASE WHEN逐个比较三个字段的值,取最大的那个排序,兼容所有MySQL版本:

SELECT *,
  SUM(IF(FIND_IN_SET('21', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line1), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line1), 1 ,0)
  ) AS total_numbers_line_1,
  SUM(IF(FIND_IN_SET('21', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line2), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line2), 1 ,0)
  ) AS total_numbers_line_2,
  SUM(IF(FIND_IN_SET('21', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('15', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('43', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('42', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('78', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('4', numbers_line3), 1 ,0) +
    IF(FIND_IN_SET('27', numbers_line3), 1 ,0)
  ) AS total_numbers_line_3
FROM cards
WHERE id_bingo = '64e3da663a617'
GROUP BY id_card
HAVING total_numbers_line_1 > 0 OR total_numbers_line_2 > 0 OR total_numbers_line_3 > 0 
ORDER BY 
  CASE
    WHEN total_numbers_line_1 >= total_numbers_line_2 AND total_numbers_line_1 >= total_numbers_line_3 THEN total_numbers_line_1
    WHEN total_numbers_line_2 >= total_numbers_line_1 AND total_numbers_line_2 >= total_numbers_line_3 THEN total_numbers_line_2
    ELSE total_numbers_line_3
  END DESC
LIMIT 20

内容的提问来源于stack exchange,提问作者Cloud5 Studios

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 09:29:55