基于INVOICEHEADER与INVOICELINES表统计产品关联发票、订单次数的技术问询
基于INVOICEHEADER与INVOICELINES表统计产品关联发票、订单次数的技术问询
我完全理解你的需求,你需要针对指定产品统计两个核心指标:一是它在多少唯一发票中出现(同发票内同产品多行只算1次),二是它在多少唯一订单中出现(同订单下多个发票的同产品只算1次)。你的示例场景描述得很清晰,接下来我会给出准确的SQL语句,同时修正你现有查询中的问题。
1. 统计产品关联的唯一发票次数
你当前的查询存在核心逻辑错误:COUNT(DISTINCT IL.PRODUCT) 在 WHERE IL.PRODUCT = '137' 的条件下永远只会返回1——因为你已经限定了单一产品,根本没有统计到发票的数量。
正确的思路是:对**发票号(InvoiceNumber)**进行去重计数,只要产品在某张发票中出现过(不管有多少行),就计为1次。
对应的SQL语句:
SELECT COUNT(DISTINCT IL.INVOICENO) AS InvoiceOccurrenceCount FROM INVOICELINES IL WITH (NOLOCK) INNER JOIN INVOICEHEADER IH WITH (NOLOCK) ON IH.INVOICENO = IL.INVOICENO WHERE IL.PRODUCT = '137' AND CONVERT(DATE, IH.[DATE]) > CONVERT(DATE, DATEADD(YEAR, -1, GETDATE()));
这个查询会返回你示例中的15,即产品137出现过的唯一发票数量。
2. 统计产品关联的唯一订单次数
根据你的描述,订单的唯一标识是 OrderNumber + AccountNumber(因为没有单独的订单表)。所以我们需要先找到所有包含目标产品的发票,关联到订单信息后,对(OrderNumber, AccountNumber)组合去重计数,确保同一个订单即使拆分到多个发票,也只算1次。
对应的SQL语句:
SELECT COUNT(DISTINCT CONCAT(IH.OrderNumber, '|', IH.AccountNumber)) AS OrderOccurrenceCount FROM INVOICELINES IL WITH (NOLOCK) INNER JOIN INVOICEHEADER IH WITH (NOLOCK) ON IH.INVOICENO = IL.INVOICENO WHERE IL.PRODUCT = '137' AND CONVERT(DATE, IH.[DATE]) > CONVERT(DATE, DATEADD(YEAR, -1, GETDATE()));
简化写法(适用于支持多列DISTINCT的SQL Server版本):
SELECT COUNT(DISTINCT (IH.OrderNumber, IH.AccountNumber)) AS OrderOccurrenceCount FROM INVOICELINES IL WITH (NOLOCK) INNER JOIN INVOICEHEADER IH WITH (NOLOCK) ON IH.INVOICENO = IL.INVOICENO WHERE IL.PRODUCT = '137' AND CONVERT(DATE, IH.[DATE]) > CONVERT(DATE, DATEADD(YEAR, -1, GETDATE()));
这个查询会返回你示例中的8,即产品137出现过的唯一订单数量。
额外提示:
你使用了WITH (NOLOCK)提示,需要注意这会带来脏读的风险,适合对数据实时性要求极高但可以容忍非一致性的场景;若业务需要准确的一致性数据,建议移除该提示。
内容来源于stack exchange
相关产品推荐
相关产品推荐

