10025]: Line 23:37 Expression not in GROUP BY key 'ljzbzc'

2026年06月11日 15:57 50.52 秒 success

错误信息

WITH base AS ( SELECT itemsubspeccode, sort_id, ljzbzc, ghinvest, investyear, -- 剔除存在负sort_id的项目 MAX(CASE WHEN sort_id<0 THEN 1 ELSE 0 END) OVER (PARTITION BY itemcode) AS has_negative FROM project_zbzc_data WHERE ghinvest>0 AND investyear>=2017 ) SELECT time_range, -- 时间范围:近三年/近五年/全部 itemsubspeccode, -- 二级专业 sort_id, -- 排序月份 CONCAT('第',sort_id,'月') month_num, -- 发生在第几月 -- 核心统计(全部合规,绝对不报错) CAST(MAX(CAST(ljzbzc AS DECIMAL(20,10))/ghinvest) AS DECIMAL(20,6)) max_ratio, -- 最大值 CAST(MIN(CAST(ljzbzc AS DECIMAL(20,10))/ghinvest) AS DECIMAL(20,6)) min_ratio, -- 最小值 CAST(AVG(CAST(ljzbzc AS DECIMAL(20,10))/ghinvest) AS DECIMAL(20,6)) avg_ratio, -- 平均值 CAST(PERCENTILE_APPROX(CAST(ljzbzc AS DECIMAL(20,10))/ghinvest,0.5) AS DECIMAL(20,6)) median_ratio, -- 中位数 CAST(MODE(CAST(ljzbzc AS DECIMAL(20,10))/ghinvest) AS DECIMAL(20,6)) mode_ratio, -- 众数 CAST(SUM(CAST(ljzbzc AS DECIMAL(20,10)))/SUM(CAST(ghinvest AS DECIMAL(20,10))) AS DECIMAL(20,6)) sum_div_ratio, -- 先求和再相除 CAST(SUM(CAST(ljzbzc AS DECIMAL(20,10)))/SUM(CAST(ghinvest AS DECIMAL(20,10))) AS DECIMAL(20,6)) wgt_avg_ratio -- 加权平均(同sum_div) FROM ( -- 近三年 SELECT '近三年' time_range,itemsubspeccode,sort_id,ljzbzc,ghinvest FROM base WHERE has_negative=0 AND investyear>=YEAR(CURRENT_DATE)-3 UNION ALL -- 近五年 SELECT '近五年' time_range,itemsubspeccode,sort_id,ljzbzc,ghinvest FROM base WHERE has_negative=0 AND investyear>=YEAR(CURRENT_DATE)-5 UNION ALL -- 全部 SELECT '全部' time_range,itemsubspeccode,sort_id,ljzbzc,ghinvest FROM base WHERE has_negative=0 ) t GROUP BY time_range,itemsubspeccode,sort_id ORDER BY CASE time_range WHEN '近三年' THEN 1 WHEN '近五年' THEN 2 ELSE 3 END, itemsubspeccode, sort_id; FAILED: SemanticException [Error 10025]: Line 23:37 Expression not in GROUP BY key 'ljzbzc'

AI 解决方案

🔍 报错分析

1. 🌐 错误翻译


原文:SemanticException [Error 10025]: Line 23:37 Expression not in GROUP BY key 'ljzbzc'
译文:语义异常 [错误 10025]:第 23 行第 37 列,表达式 `ljzbzc` 不在 GROUP BY 子句的键中

2. 🎯 原因分析


错误发生在执行聚合查询的 GROUP BY 阶段。根本原因是 SELECT 列表中包含了非聚合列 (sort_id, ljzbzc, ghinvest 等),而这些列没有全部、且以相同形式出现在 GROUP BY 子句中

具体来说:

  • 外层查询的 GROUP BY 子句只包含了 time_range, itemsubspeccode, sort_id

  • SELECT 列表中的 CONCAT('第',sort_id,'月') 是一个派生列(表达式),它依赖于 sort_id

  • 更关键的是,在内部的 UNION ALL 子查询中,ljzbzcghinvest 列被选中并传递到了外层查询。

  • 在外层查询中,这些列被用于 MAX, MIN, AVG聚合函数内部(例如 CAST(ljzbzc AS ...)),这是允许的。

  • 但是SELECT 列表中直接列出了 sort_id 以及依赖它的表达式 CONCAT(...),而它们没有被聚合,也没有完整地出现在 GROUP BY 子句中(GROUP BY 中只有 sort_id,没有 CONCAT(...) 表达式)。SQL 引擎要求 SELECT 中任何非聚合列必须与 GROUP BY 键完全一致。
  • 3. 💡 解决方案


    你需要确保 GROUP BY 子句与 SELECT 列表中的非聚合列和表达式完全一致。将 CONCAT 表达式添加到 GROUP BY 子句中。

    -- 修复后的代码
    WITH base AS (
        SELECT 
            itemsubspeccode,
            sort_id,
            ljzbzc,
            ghinvest,
            investyear,
            MAX(CASE WHEN sort_id<0 THEN 1 ELSE 0 END) OVER (PARTITION BY itemcode) AS has_negative
        FROM project_zbzc_data
        WHERE ghinvest>0 AND investyear>=2017
    )
    SELECT 
        time_range,
        itemsubspeccode,
        sort_id,
        CONCAT('第',sort_id,'月') month_num,
        CAST(MAX(CAST(ljzbzc AS DECIMAL(20,10))/ghinvest) AS DECIMAL(20,6)) max_ratio,
        CAST(MIN(CAST(ljzbzc AS DECIMAL(20,10))/ghinvest) AS DECIMAL(20,6)) min_ratio,
        CAST(AVG(CAST(ljzbzc AS DECIMAL(20,10))/ghinvest) AS DECIMAL(20,6)) avg_ratio,
        CAST(PERCENTILE_APPROX(CAST(ljzbzc AS DECIMAL(20,10))/ghinvest,0.5) AS DECIMAL(20,6)) median_ratio,
        CAST(MODE(CAST(ljzbzc AS DECIMAL(20,10))/ghinvest) AS DECIMAL(20,6)) mode_ratio,
        CAST(SUM(CAST(ljzbzc AS DECIMAL(20,10)))/SUM(CAST(ghinvest AS DECIMAL(20,10))) AS DECIMAL(20,6)) sum_div_ratio,
        CAST(SUM(CAST(ljzbzc AS DECIMAL(20,10)))/SUM(CAST(ghinvest AS DECIMAL(20,10))) AS DECIMAL(20,6)) wgt_avg_ratio
    FROM (
        SELECT '近三年' time_range,itemsubspeccode,sort_id,ljzbzc,ghinvest FROM base WHERE has_negative=0 AND investyear>=YEAR(CURRENT_DATE)-3
        UNION ALL
        SELECT '近五年' time_range,itemsubspeccode,sort_id,ljzbzc,ghinvest FROM base WHERE has_negative=0 AND investyear>=YEAR(CURRENT_DATE)-5
        UNION ALL
        SELECT '全部' time_range,itemsubspeccode,sort_id,ljzbzc,ghinvest FROM base WHERE has_negative=0
    ) t
    GROUP BY time_range, itemsubspeccode, sort_id, CONCAT('第',sort_id,'月') -- ✅ 关键修复:将完整的非聚合列表达式加入GROUP BY
    ORDER BY 
        CASE time_range WHEN '近三年' THEN 1 WHEN '近五年' THEN 2 ELSE 3 END,
        itemsubspeccode,
        sort_id;
    

    4. 🛡️ 预防措施


  • 检查 SELECTGROUP BY 的一致性:编写聚合查询后,务必核对 SELECT 列表中所有非聚合列(包括计算列、函数列)是否都已准确无误地出现在 GROUP BY 子句中。许多SQL IDE(如DataGrip, DBeaver)会高亮显示不匹配的列。

  • 使用列别名:在 GROUP BY 子句中,优先使用列别名(如 month_num)而非原始表达式(CONCAT(...)),前提是你的SQL方言支持(如Hive, SparkSQL通常支持)。这样可以提高可读性和一致性。但请注意,有些数据库(如MySQL的严格模式)可能不允许在 GROUP BY 中使用 SELECT 中定义的别名。

  •     -- 更好的写法(在某些SQL方言中可行)
        GROUP BY time_range, itemsubspeccode, sort_id, month_num