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

MySQL UNION合并独立SQL查询报1064错误及成绩报表实现问题

报错根因
  • 和NULL值无关,语法错误的直接原因是UNION拼接的单个子查询中,不能独立使用ORDER BY子句(除非子查询包裹括号且搭配LIMIT做结果限制),你在第一个SELECT块末尾写的order by B.grade desc,A.name直接接在union关键字前,触发了语法解析错误。
  • 另外你的排序逻辑本身也不符合UNION的执行规则:UNION最终返回的是一个完整结果集,只能有一套全局排序规则,无法让两段结果分别按不同规则排序后再拼接。
  • 额外说明:你原SQL漏查了业务要求的Mark列,即使语法修正后输出字段也不符合需求。
修正后的UNION实现

如果要保留UNION写法,需要把两个查询块作为子查询包裹,在外层统一做排序。因为两段查询的分数区间完全不重叠,用UNION ALL代替UNION可以省去去重开销,执行效率更高:

SELECT
    id,
    Name,
    Grade,
    Marks
FROM (
    SELECT 
        A.id,
        A.Name, 
        B.Grade,
        A.Marks
    FROM Students A, Grades B 
    WHERE A.Marks >= B.min_mark 
      AND A.Marks <= B.max_mark 
      AND B.Grade >= 8
    UNION ALL
    SELECT 
        A.id,
        NULL AS Name, 
        B.Grade,
        A.Marks
    FROM Students A, Grades B 
    WHERE A.Marks >= B.min_mark 
      AND A.Marks <= B.max_mark 
      AND B.Grade < 8
) t
ORDER BY 
    Grade DESC,
    -- 8分及以上按姓名升序
    CASE WHEN Grade >= 8 THEN Name END ASC,
    -- 7分及以下按分数升序
    CASE WHEN Grade < 8 THEN Marks END ASC
无UNION的替代方案

不需要拆分两段查询,直接通过CASE表达式单次关联查询即可实现所有需求,逻辑更简洁,执行效率也更高:

SELECT
    A.id,
    -- 低于8分姓名显示为NULL
    CASE WHEN B.Grade >= 8 THEN A.Name ELSE NULL END AS Name,
    B.Grade,
    A.Marks
FROM Students A
INNER JOIN Grades B 
  ON A.Marks BETWEEN B.min_mark AND B.max_mark
ORDER BY
    -- 全局按成绩降序
    B.Grade DESC,
    -- 8分及以上同分段按姓名升序
    CASE WHEN B.Grade >= 8 THEN A.Name END ASC,
    -- 7分及以下同分段按分数升序
    CASE WHEN B.Grade < 8 THEN A.Marks END ASC

该写法用显式JOIN替代了隐式逗号关联,可读性更好;所有业务规则都通过SELECT和ORDER BY中的CASE表达式直接实现,不需要额外合并结果集。

内容的提问来源于stack exchange,提问作者Leos Literak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 22:12:29