T-SQL高级连接:多条件客户采购总额统计(含无采购客户)求助
修正后的T-SQL代码及问题说明
原代码核心问题
- 主查询从
Invoice表出发左连Customer,直接导致无采购记录的客户被遗漏,必须以符合条件的Customer表作为查询起点 - 字段引用错误:
InvoiceLine表不存在CustomerId,需通过Invoice.CustomerId关联;第二个子查询表别名写错(LI应为IL);I.TRCODE应为表定义的I.InvoiceType - 产品代码逻辑错误:退货发票的产品也需限定为
GTN开头(原代码写了WLT.%,不符合需求) - 日期条件误用:需求明确统计发票日期,应使用
Invoice.DateIssued而非InvoiceLine.Date - 子查询重复筛选客户条件,冗余且易出错
- 未处理无记录时的空值显示逻辑
修正后的代码
SELECT C.Name, -- 计算销售总额减退货总额,无记录时返回NULL NULLIF( SUM(CASE WHEN I.InvoiceType = 8 THEN IL.LineTotal ELSE 0 END) - SUM(CASE WHEN I.InvoiceType = 3 THEN IL.LineTotal ELSE 0 END), 0 ) AS 扣除退货后的采购总额 FROM Customer C LEFT JOIN Invoice I ON C.CustomerId = I.CustomerId AND YEAR(I.DateIssued) = 2022 AND MONTH(I.DateIssued) = 10 -- 限定发票日期为2022年10月 LEFT JOIN InvoiceLine IL ON I.InvoiceId = IL.InvoiceId LEFT JOIN Product P ON IL.ProductId = P.ProductId AND P.Code LIKE 'GTN%' -- 限定产品代码以GTN开头 WHERE C.Status = 0 AND C.Region = 'London' AND C.Code LIKE 'M%' -- 客户Code以M开头 GROUP BY C.CustomerId, C.Name -- 按客户唯一标识分组,确保单客户单行 ORDER BY C.Name;
关键逻辑说明
- 查询起点:从
Customer表出发,确保所有符合筛选条件的客户(含无采购记录的)都能被列出 - 条件放置:将发票日期、产品代码的筛选放在
LEFT JOIN的ON子句中,避免过滤掉无采购记录的客户 - 空值处理:用
NULLIF将无交易时的0转为NULL,符合需求中“无采购记录显示空值”的要求 - 分组逻辑:按
CustomerId(唯一标识)和Name分组,保证每个客户仅返回一行结果
内容的提问来源于stack exchange,提问作者Subliminal Hash
相关产品推荐
相关产品推荐

