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

如何在SQL Server子查询中添加日期范围过滤器并修正报表数据异常

问题分析与解决方案

问题出在你的左连接逻辑和sum计算的范围上——虽然你在收款单(ODPI)的子查询里限制了日期,但左连接意味着即使收款日期不在2019年,只要销售订单符合条件,关联的DPI1(税明细)记录依然会被纳入sum计算,最终导致不该出现的fbdwnp without vat数据被统计进来。

下面给出两种针对性的解决方案,你可以根据业务需求选择:


方案1:保留订单但仅统计合规收款的税明细数据

如果你需要保留销售日期在2019年的所有订单,但仅当收款日期也在2019年时才计算fbdwnp without vat,可以修改sum表达式,添加对收款日期的判断:

select 
  a.DocDate as 'Order Date',
  f.DocDate as 'Collection Date',
  b.LineTotal as 'fbsales amount',
  a.SlpCode,
  a.CardCode,
  b.DocEntry,
  -- 修改sum逻辑,仅统计收款日期在2019年的税明细
  sum(
    case 
      when f.DocDate is not null -- 确保对应的收款单在目标日期范围内
      then case 
             when e.TaxCode = 'NBT2' then cast(e.LineTotal as decimal(22,8)) /1.02 
             when e.TaxCode = 'N2+V15' then (cast(e.LineTotal as decimal(22,8)) /1.173) 
             when e.TaxCode = 'VAT8' then (cast(e.LineTotal as decimal(22,8)) /1.08) 
             else e.LineTotal 
           end 
      else 0 -- 收款日期不在范围内时,该字段显示为0
    end
  ) as 'fbdwnp without vat',
  b.LineNum 
from ORDR a 
left join RDR1 b on b.DocEntry = a.DocEntry 
left join OSLP c on c.SlpCode = a.SlpCode 
left join OITM d on d.ItemCode = b.ItemCode 
left Join (select TaxCode,LineTotal,BaseEntry,BaseLine,DocEntry from DPI1 where [TargetType]<>'14') e on e.BaseEntry = b.DocEntry and e.BaseLine = b.LineNum 
left Join (select DocEntry,DocDate From ODPI where CANCELED = 'N' and DocDate between '20190101' and '20191231') f on f.DocEntry = e.DocEntry 
where a.CANCELED = 'N' and d.U_Product_Type = 'Facebook' and a.DocDate between '20190101' and '20191231' and a.SlpCode = 68 
group by c.SlpName,a.SlpCode,b.LineTotal,d.DocEntry,a.CardCode,c.SlpName,b.DocEntry,a.DocDate,b.LineNum,f.DocDate

这样,当收款日期为2020-01-09时,f.DocDate会因为子查询的过滤而变为NULL,对应的税明细不会被计入sum,最终fbdwnp without vat会显示为0,符合你只展示fbsales amount的需求。


方案2:直接过滤掉收款日期不合规的订单

如果你不需要保留收款日期不在2019年的销售订单,可以选择以下两种方式之一:

方式A:将左连接收款单改为内连接

-- 把left Join改成inner Join,只保留有合规收款记录的订单
inner Join (select DocEntry,DocDate From ODPI where CANCELED = 'N' and DocDate between '20190101' and '20191231') f on f.DocEntry = e.DocEntry

方式B:在where条件中添加收款日期校验

在where子句末尾追加:

and f.DocDate is not null

这两种方式都会直接过滤掉收款日期不在2019年的订单,报表中只会显示销售和收款都在2019年的记录。


额外优化建议

  • 你的group by子句包含了c.SlpName,但select中没有输出该字段,这可能触发SQL语法错误(取决于数据库模式),建议要么在select中添加c.SlpName,要么从group by中移除该字段。
  • 日期条件尽量使用标准格式(如'2019-01-01'),避免数据库解析日期时出现异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:27:52