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

SQL条件计算列需求:按客户、年份及销售类型统计收入

解决按客户统计不同年份、销售类型的收入(行列转换)需求

没问题,针对你的Invoice表统计需求,我们可以用条件聚合的方式来实现行列转换,把年份和销售类型的组合转成结果表中的列。这种方法适用于绝大多数主流SQL数据库(MySQL、SQL Server、PostgreSQL等)。

先回顾下你的原始表结构和数据:

InvNoDateCustNameTypeOfSaleTaxGrand
212019AAT1$1.00$10.00
222019AAT2$2.00$20.00
232019BBT1$1.00$10.00
242020AAT1$1.00$10.00
252020BBT1$1.00$10.00
262020BBT2$2.00$20.00

你的目标是计算Revenue = Grand - Tax,并按客户统计不同年份、销售类型的收入总和,得到如下结构的结果:

CustNameRevenue TypeT1 2019Revenue TypeT2 2019Revenue TypeT1 2020Revenue TypeT2 2020
AA$9.00$18.00$9.00$0.00
BB$9.00$0.00$9.00$18.00

解决方案SQL代码

SELECT
    CustName,
    -- 2019年T1类型的收入总和
    CONCAT('$', FORMAT(SUM(CASE WHEN Date = 2019 AND TypeOfSale = 'T1' THEN (Grand - Tax) ELSE 0 END), 2)) AS 'Revenue TypeT1 2019',
    -- 2019年T2类型的收入总和
    CONCAT('$', FORMAT(SUM(CASE WHEN Date = 2019 AND TypeOfSale = 'T2' THEN (Grand - Tax) ELSE 0 END), 2)) AS 'Revenue TypeT2 2019',
    -- 2020年T1类型的收入总和
    CONCAT('$', FORMAT(SUM(CASE WHEN Date = 2020 AND TypeOfSale = 'T1' THEN (Grand - Tax) ELSE 0 END), 2)) AS 'Revenue TypeT1 2020',
    -- 2020年T2类型的收入总和
    CONCAT('$', FORMAT(SUM(CASE WHEN Date = 2020 AND TypeOfSale = 'T2' THEN (Grand - Tax) ELSE 0 END), 2)) AS 'Revenue TypeT2 2020'
FROM
    Invoice
GROUP BY
    CustName
ORDER BY
    CustName;

代码解释

  1. 核心逻辑:条件聚合

    • 用CASE WHEN语句筛选出符合特定年份和销售类型的记录,计算对应的Grand - Tax,不符合的则返回0
    • 用SUM()函数对筛选后的结果求和,得到该客户对应分组的收入总和
  2. 金额格式化

    • FORMAT(..., 2)用来确保结果保留两位小数
    • CONCAT('$', ...)用来给金额加上$符号,如果你使用的是SQL Server,可能需要用STR()或者CAST配合CONCAT,比如:CONCAT('$', CAST(SUM(...) AS DECIMAL(10,2)))
  3. 分组与排序

    • GROUP BY CustName确保我们按客户进行统计
    • ORDER BY CustName让结果按客户名称排序,更清晰

注意事项

  • 如果你的Date字段是日期类型(不是单纯的年份数字),需要用年份提取函数,比如YEAR(Date) = 2019来替代Date = 2019
  • 不同数据库的格式化函数略有差异,比如PostgreSQL用TO_CHAR,可以根据你的数据库类型调整格式化部分的代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 12:42:44