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

MySQL子分组数据查询:统计低于阈值的发票数量

问题:客户销售数据多维度统计(含低额发票计数)

现有销售数据中,每个客户单日可生成多张发票,每张发票包含多条记录。需要统计以下指标:

  • 客户总销售额
  • 下单天数
  • 发票总数
  • 单票平均金额
  • 总金额低于£25的发票数量

目前已实现前四项统计的SQL:

select Customer,sum(Sales_Total) AS Sales Total,
    count(distinct Invoice_Date) AS Days ordered Count,
    COUNT(distinct Invoice_Number) AS Invoice Count,
    sum(Sales_Total)/count(distinct Invoice_Number) AS Average per Invoice,
from sales_2023
group by Customer
order by Customer;

尝试过窗口函数和子查询,但未成功统计出低于阈值的发票数,寻求解决思路。

数据示例

Customer | Invoice Date | Invoice Number | Stock | Total Value
---------------------------------------------------------------
Acme     | 01/01/2023   | 1234           | Cod   | £20
Acme     | 01/01/2023   | 1234           | Hake  | £15
Acme     | 01/01/2023   | 2468           | Cod   | £10
Acme     | 01/01/2023   | 2468           | Hake  | £12
Acme     | 02/01/2023   | 3699           | Cod   | £20
Acme     | 02/01/2023   | 4567           | Hake  | £15
Acme     | 03/01/2023   | 9876           | Cod   | £10
Acme     | 03/01/2023   | 9876           | Hake  | £1
Beta     | 01/01/2023   | 8976           | Cod   | £10
Beta     | 01/01/2023   | 8976           | Hake  | £15
Beta     | 01/01/2023   | 5432           | Cod   | £5
Beta     | 01/01/2023   | 5432           | Hake  | £12
Beta     | 02/01/2023   | 2233           | Cod   | £20
Beta     | 02/01/2023   | 2233           | Hake  | £15
Beta     | 02/01/2023   | 1590           | Cod   | £10
Beta     | 02/01/2023   | 1590           | Hake  | £15

期望结果

Customer | Sales Total | Days Ordered Count | Invoice Count | Average per Invoice |  Invoice < £25
-------------------------------------------------------------------------------------------------
Acme     |     £103    |           3        |      5        |          £20.60     |      4
Beta     |     £102    |           2        |      4        |          £25.50     |      1

解决方案

核心思路是先计算每张发票的总金额,因为原表中每条记录是发票的明细项,单条记录的Total Value只是单个商品的金额,不是整张发票的总额。只有先得到单票总额,才能判断是否低于£25,再基于此做客户维度的汇总统计。

完整SQL(用CTE实现)

WITH invoice_summary AS (
    SELECT 
        Customer,
        Invoice_Number,
        -- 去掉£符号,转成数值类型再求和,得到单张发票的总金额
        SUM(CAST(REPLACE(Total_Value, '£', '') AS DECIMAL(10,2))) AS invoice_total
    FROM sales_2023
    GROUP BY Customer, Invoice_Number
)
SELECT 
    isum.Customer,
    SUM(isum.invoice_total) AS `Sales Total`,
    -- 关联原表获取去重后的下单天数
    COUNT(DISTINCT s.Invoice_Date) AS `Days Ordered Count`,
    COUNT(isum.Invoice_Number) AS `Invoice Count`,
    -- 保留两位小数贴合期望结果
    ROUND(SUM(isum.invoice_total)/COUNT(isum.Invoice_Number), 2) AS `Average per Invoice`,
    -- 用CASE WHEN标记符合条件的发票,求和得到数量
    SUM(CASE WHEN isum.invoice_total < 25 THEN 1 ELSE 0 END) AS `Invoice < £25`
FROM invoice_summary isum
JOIN sales_2023 s ON isum.Customer = s.Customer AND isum.Invoice_Number = s.Invoice_Number
GROUP BY isum.Customer
ORDER BY isum.Customer;

关键说明

  • 第一步的CTEinvoice_summary是核心:按Customer和Invoice_Number分组,计算每张发票的总金额,这里必须处理Total Value里的英镑符号,转成数值才能正确求和。
  • 关联原表是为了获取Invoice_Date,统计客户的下单天数(去重后计数)。
  • 用CASE WHEN判断单票总额是否低于25,符合条件记1,否则0,对这个结果求和就是低额发票的数量。

子查询版本(如果不支持CTE)

如果你的SQL环境不支持CTE,可以把中间逻辑放到子查询里,效果完全一致:

SELECT 
    sub.Customer,
    SUM(sub.invoice_total) AS `Sales Total`,
    COUNT(DISTINCT s.Invoice_Date) AS `Days Ordered Count`,
    COUNT(sub.Invoice_Number) AS `Invoice Count`,
    ROUND(SUM(sub.invoice_total)/COUNT(sub.Invoice_Number), 2) AS `Average per Invoice`,
    SUM(CASE WHEN sub.invoice_total < 25 THEN 1 ELSE 0 END) AS `Invoice < £25`
FROM (
    SELECT 
        Customer,
        Invoice_Number,
        SUM(CAST(REPLACE(Total_Value, '£', '') AS DECIMAL(10,2))) AS invoice_total
    FROM sales_2023
    GROUP BY Customer, Invoice_Number
) sub
JOIN sales_2023 s ON sub.Customer = s.Customer AND sub.Invoice_Number = s.Invoice_Number
GROUP BY sub.Customer
ORDER BY sub.Customer;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 01:10:23