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

SQL报错解析:子查询未用EXISTS时SELECT限制及多表统计需求

报错信息

当子查询未使用EXISTS引入且包含多个查询时,SELECT列表中只能指定一个表达式。

数据源表

表1

StudentIdStuName已缴学校费用
1s110000
2s240000
3s120000
4s410000
30,22,48,60s6,s8,s9,s103300
8s121200
10s45000
12s164000
18,16s20,s2110000
20s240000
22s630000

表2

StudentIdStuName已缴学费
66s6610000
27s2740000
3s320000
54s410000
30,22,48,60s6,s8,s9,s103300
8s121200
40s145000
12s164000
18,16s20,s2110000
20s2040000
25s2530000

预期输出

已缴学校费用已缴学费Count3Count4
Student110000700042
Student2400001000035
Student370000600043
Student480000400021
Student55000900014

问题解决与SQL实现

报错原因

该错误是因为在非EXISTS驱动的子查询中,SELECT子句返回了多列/多表达式,而SQL语法规定这种场景下子查询只能返回单个表达式。比如SELECT * FROM t WHERE col IN (SELECT a,b FROM t2)这类写法就会触发报错。

实现思路

  1. 先拆分原表中逗号分隔的StudentId字段(以SQL Server为例,使用STRING_SPLIT,其他数据库可替换为对应拆分函数);
  2. 分别对两个表按预期的Student分组统计费用和计数;
  3. 通过全连接合并两个表的统计结果,规避子查询返回多列的问题。

完整SQL语句

-- 处理表1的拆分与统计
WITH Table1_Stats AS (
    SELECT
        CASE 
            WHEN 已缴学校费用 <= 10000 THEN 'Student1'
            WHEN 已缴学校费用 <= 40000 THEN 'Student2'
            WHEN 已缴学校费用 <= 70000 THEN 'Student3'
            WHEN 已缴学校费用 <= 80000 THEN 'Student4'
            ELSE 'Student5'
        END AS StudentGroup,
        SUM(已缴学校费用) AS 已缴学校费用,
        COUNT(*) AS Count3
    FROM (
        SELECT 
            s.value AS StudentId,
            t.StuName,
            t.已缴学校费用
        FROM 表1 t
        CROSS APPLY STRING_SPLIT(t.StudentId, ',') s
    ) t
    GROUP BY 
        CASE 
            WHEN 已缴学校费用 <= 10000 THEN 'Student1'
            WHEN 已缴学校费用 <= 40000 THEN 'Student2'
            WHEN 已缴学校费用 <= 70000 THEN 'Student3'
            WHEN 已缴学校费用 <= 80000 THEN 'Student4'
            ELSE 'Student5'
        END
),
-- 处理表2的拆分与统计
Table2_Stats AS (
    SELECT
        CASE 
            WHEN 已缴学费 <= 7000 THEN 'Student1'
            WHEN 已缴学费 <= 10000 THEN 'Student2'
            WHEN 已缴学费 <= 6000 THEN 'Student3'
            WHEN 已缴学费 <= 4000 THEN 'Student4'
            ELSE 'Student5'
        END AS StudentGroup,
        SUM(已缴学费) AS 已缴学费,
        COUNT(*) AS Count4
    FROM (
        SELECT 
            s.value AS StudentId,
            t.StuName,
            t.已缴学费
        FROM 表2 t
        CROSS APPLY STRING_SPLIT(t.StudentId, ',') s
    ) t
    GROUP BY 
        CASE 
            WHEN 已缴学费 <= 7000 THEN 'Student1'
            WHEN 已缴学费 <= 10000 THEN 'Student2'
            WHEN 已缴学费 <= 6000 THEN 'Student3'
            WHEN 已缴学费 <= 4000 THEN 'Student4'
            ELSE 'Student5'
        END
)
-- 合并统计结果
SELECT
    COALESCE(t1.StudentGroup, t2.StudentGroup) AS '',
    COALESCE(t1.已缴学校费用, 0) AS 已缴学校费用,
    COALESCE(t2.已缴学费, 0) AS 已缴学费,
    COALESCE(t1.Count3, 0) AS Count3,
    COALESCE(t2.Count4, 0) AS Count4
FROM Table1_Stats t1
FULL JOIN Table2_Stats t2 ON t1.StudentGroup = t2.StudentGroup
ORDER BY COALESCE(t1.StudentGroup, t2.StudentGroup);

说明

  • 字符串拆分:如果使用MySQL/PostgreSQL等数据库,需替换STRING_SPLIT为对应函数(如MySQL用递归拆分,PostgreSQL用STRING_TO_ARRAY);
  • 分组规则:示例中的分组逻辑是匹配预期输出的费用区间,可根据实际业务需求调整;
  • 报错规避:通过CTE分别处理两个表的统计,再用JOIN合并结果,彻底避免了子查询返回多列的违规写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:42:27