【问题标题】:Why do these sum operations not "add up" as they should?为什么这些求和运算没有按应有的方式“加起来”?
【发布时间】:2026-01-10 06:30:01
【问题描述】:

注意:这是this questionthis questionthis question 的后续[on,up]。

所有的回答都让我前进,但即使是最后一个,虽然它改善了问题,但并没有完全解决这个问题。

这个查询:

select monthlysales, MemberNo from ReportingMonthlySales
where unit = 'Abuelos' and CYear = 2017 and cmonth = 3

...返回一堆行,其中每月销售总额为 $364,121.69

但是,当我尝试将这些月销售额分成四类时,虽然它们的总和应该是相同的,但总和实际上是天文数字的“巨大”——以下代码返回了 23,924,211.30 的巨大膨胀值

2400 万美元几乎是实际总额 36.4 万美元的 70 倍。为什么会发生这种“疯狂”的通货膨胀?

这是花哨的裤子,但显然是被骗的代码:

declare @Unit varchar(30);
declare @Year int = 2017;
declare @Month int = 3;
declare @paramdate datetime;
set @paramdate = convert(datetime,convert(char(4),@Year)
                +right('0'+convert(varchar(2),@month),2)
                +'01') 

IF OBJECT_ID('tempdb.dbo.#Units', 'U') IS NOT NULL
DROP TABLE #Units

select distinct unit
into #Units
from ReportingMonthlySales;

select 
    u.Unit
  , New      = sum(case when ccl.Subcategory = 'New'      then rms.MonthlySales else 0 end)
  , Assumed  = sum(case when ccl.Subcategory = 'Assumed'  then rms.MonthlySales else 0 end)
  , Existing = sum(case when ccl.Subcategory = 'Existing' then rms.MonthlySales else 0 end)
  , Organic  = sum(case when ccl.Subcategory = 'Organic'  then rms.MonthlySales else 0 end)
from #Units u
  left join CustomerCategoryLog ccl 
    on u.Unit = ccl.Unit
   and @paramdate >= ccl.begindate and
   (@paramdate <= ccl.enddate OR ccl.enddate is null)
  left join ReportingMonthlySales rms
    on u.Unit = rms.Unit
   and rms.cyear  = @year
   and rms.cmonth = @month
group by u.unit;

The two tables queried are:

CustomerCategoryLog
-------------------
MemberNo (VarChar)
Unit (VarChar)
Custno (VarChar)
Category (VarChar)
Subcategory (VarChar)
BeginDate (DateTime)
EndDate (DateTime)
ChangedBy (VarChar)
ChangedOn (DateTime)

ReportingMonthlySales
---------------------
AutoID (Int)
Unit (VarChar)
MemberNo (VarChar)
NumUnits (Int)
MonthlySales (Money)
CYear (Int)
Cmonth (Int)
CreateDate (DateTime)

fancy-pants sql 中是否有问题,或者...?!?

【问题讨论】:

  • 我敢打赌,如果您删除查询的总和部分并仅添加其他几列以查看实际结果集(例如 Id 列),您会注意到查询的结果集是重复行,这意味着您的联接需要更多微调。
  • 同意@Sparrow,尤其是因为 CustomerCategoryLog 似乎是一个日志表,并且可能导致一对多连接。
  • 也运行这个,让我们知道返回了多少行 - select * from CustomerCategoryLog where unit = 'Abuelos'
  • 查看 CustomerCategoryLog 和 ReportingMonthlySales 之间的连接。按子类别划分的细分是 CustomerCategoryLog 的一部分,但除非 Unit 在它们之间是唯一的,否则 CCL 表中的单行与 RMS 表中的单行之间没有实际关联。很可能您需要将客户加入到他购买的汽车中,然后将其加入到 ReportingMonthlySales 表中才能正确分解。

标签: sql sql-server tsql


【解决方案1】:

我怀疑左连接和Or ccl.enddate is null 生成了一个一对多

也许直接的内连接会纠正通货膨胀

select 
    u.Unit
  , New      = sum(case when ccl.Subcategory = 'New'      then rms.MonthlySales else 0 end)
  , Assumed  = sum(case when ccl.Subcategory = 'Assumed'  then rms.MonthlySales else 0 end)
  , Existing = sum(case when ccl.Subcategory = 'Existing' then rms.MonthlySales else 0 end)
  , Organic  = sum(case when ccl.Subcategory = 'Organic'  then rms.MonthlySales else 0 end)
from #Units u
join CustomerCategoryLog   ccl on u.Unit = ccl.Unit and @paramdate >= ccl.begindate and @paramdate <= ccl.enddate
join ReportingMonthlySales rms on u.Unit = rms.Unit and rms.cyear  = @year and rms.cmonth = @month
group by u.unit;

【讨论】:

  • @B.ClayShannon 恭喜您了解您的结果应该是什么。我曾经目睹我们的 TECH 支持甚至没有眨眼,当月净利息收入达到 17.8 万亿美元
  • 谢谢 - 那么,你可能会对我收集的他的俏皮话、格言和批评感兴趣。位于康涅狄格州雷丁的吐温博物馆(吐温的最后住所)将其作为礼物送给演讲嘉宾。
  • @B.ClayShannon 这是一个不错的小惊喜,当然没有必要,但我非常感谢您的考虑 - 谢谢
  • @B.ClayShannon "Andrew Carnegie" 模式......这很有趣。我的下一个职业将是定制家具。 Horse Farm, to Hotel, to Banking, to Consulting……接下来是ME TIME。期待成为那个留着胡子的奇怪家伙。
  • 我有时很想进入银行业,就像约翰·迪林格一样。
【解决方案2】:

您正在 RMS 表和这些其他表之间进行连接。您的代码假定它将为 RMS 表中的每条记录找到一条记录。这不是真的。这是报告和汇总多行的原因。我认为对于特定单元和@paramdate,很可能有多个 CCL 条目。

【讨论】:

    【解决方案3】:

    我认为这是导致重复的原因

    select distinct unit
    into #Units
    from ReportingMonthlySales;
    

    您基本上从表中插入了相同的数据并在左连接处使用..

    试试这个更新的脚本

      SELECT
      rms.Unit,
      New = SUM(CASE
        WHEN ccl.Subcategory = 'New' THEN rms.MonthlySales
        ELSE 0
      END),
      Assumed = SUM(CASE
        WHEN ccl.Subcategory = 'Assumed' THEN rms.MonthlySales
        ELSE 0
      END),
      Existing = SUM(CASE
        WHEN ccl.Subcategory = 'Existing' THEN rms.MonthlySales
        ELSE 0
      END),
      Organic = SUM(CASE
        WHEN ccl.Subcategory = 'Organic' THEN rms.MonthlySales
        ELSE 0
      END)
    FROM ReportingMonthlySales rms
    inner JOIN CustomerCategoryLog ccl
      ON rms.Unit = ccl.Unit
    where
      AND @paramdate >= ccl.begindate
      AND (@paramdate <= isnull(ccl.enddate,getdate())
      )
     AND
       rms.cyear = @year
      AND rms.cmonth = @month
    GROUP BY rms.unit;
    

    【讨论】:

    • 这也产生了巨大的结果——Applebees 一个月的收入接近 30 亿美元。那是很多肋骨!
    • @B.ClayShannon 哈哈.. 我错过了加入.. 应该是内部
    【解决方案4】:

    顾名思义,您的 CustomerCategoryTable 可能对同一个 UnitNo 的不同 CustNo 有多个记录,这使您的第一个左连接返回重复的行,这将使月销售额成倍增加,我认为您的解决方案没有查询,除非您尝试为一个简单的信息修复架构本身,即您正在尝试查找每个单位的不同子类别的月销售额,并且您的 ReportingMonthlySales 表没有关于子类别的任何信息。

    【讨论】:

      最近更新 更多