如何用单条MySQL语句统计符合条件的不含税与增值税总额
MySQL单语句实现特定单据总额统计
数据表与需求说明
现有数据表
| DocumentNumber | Amount | Account | BuyerName | BuyerVat | | 123 | 100 | 6110 | Name 01 | null | | 123 | 21 | 5727 | Name 01 | null | | 456 | 100 | 6112 | Name 02 | null | | 456 | 12 | 5732 | Name 02 | null | | 789 | 10 | 6112 | Name 02 | null | | 789 | 1.2 | 5732 | Name 02 | null |
统计规则
需统计满足以下条件的两项总额:
- 不含税总额(TotalWithoutVat):科目为6110/6112的金额总和,且对应单据的该类金额≥100;
- 增值税总额(TotalVat):上述符合条件的单据中,非6110/6112科目的金额总和;
- 额外条件:BuyerVat字段为null。
期望输出
[0] => Array ( [TotalWithoutVat] => 200.00 [TotalVat] => 33.00 )
单语句实现方案
方案1:子查询筛选合格单据(兼容所有MySQL版本)
SELECT SUM(CASE WHEN Account IN (6110, 6112) THEN Amount ELSE 0 END) AS TotalWithoutVat, SUM(CASE WHEN Account NOT IN (6110, 6112) THEN Amount ELSE 0 END) AS TotalVat FROM your_table WHERE DocumentNumber IN ( -- 子查询先筛选出符合要求的单据编号 SELECT DocumentNumber FROM your_table WHERE BuyerVat IS NULL AND Account IN (6110, 6112) GROUP BY DocumentNumber HAVING SUM(Amount) >= 100 ) AND BuyerVat IS NULL;
逻辑解析
- 子查询先锁定符合条件的单据:过滤BuyerVat为null、科目是6110/6112的记录,按单据分组后仅保留不含税总额≥100的单据编号;
- 外层查询基于这些编号,分别汇总不含税金额和增值税金额;
- 执行后直接得到目标统计结果。
方案2:窗口函数预计算(MySQL 8.0+适用)
WITH doc_without_vat_cte AS ( SELECT *, -- 计算每个单据的不含税总额 SUM(CASE WHEN Account IN (6110, 6112) THEN Amount ELSE 0 END) OVER (PARTITION BY DocumentNumber) AS doc_total_without_vat FROM your_table WHERE BuyerVat IS NULL ) SELECT SUM(CASE WHEN Account IN (6110, 6112) THEN Amount ELSE 0 END) AS TotalWithoutVat, SUM(CASE WHEN Account NOT IN (6110, 6112) THEN Amount ELSE 0 END) AS TotalVat FROM doc_without_vat_cte WHERE doc_total_without_vat >= 100;
逻辑解析
- 通过CTE为每条记录标记所属单据的不含税总额;
- 筛选出不含税总额达标记录后,直接汇总两类金额;
- 代码结构更清晰,可读性更强。
结果验证
将上述SQL中的your_table替换为实际表名执行,会得到如下结果,与需求完全匹配:
TotalWithoutVat | TotalVat ----------------|--------- 200.00 | 33.00
内容的提问来源于stack exchange,提问作者Andris
相关产品推荐
相关产品推荐

