【问题标题】:When using sum, case and negate value, I get doubled value back当使用 sum、case 和 negate 值时,我得到了双倍的值
【发布时间】:2020-12-14 09:17:36
【问题描述】:

当尝试使用 sum 函数时,我在使用 CASE 和否定值时得到了错误的值,我不知道为什么。 (否定的值被减去两次)。

我的目标是在类型 c_calcType 为 'calcCorrection' 的情况下从 sum/groupBy 中减去它。

使用时:

SELECT Sum(CASE WHEN c_calcType = 'calcCorrection' THEN (c_calcValue * -1)
                ELSE c_calcValue END) as c_calcValue,
       c_parentID
FROM DB_Calc
WHERE c_parentID is not null AND c_state <> 'deactiveted'
GROUP BY c_parentID

我得到的值 (c_calcValue) 返回 500,但我不包括 750。过滤和进行手动计算时,我得到了正确的值。

作为示例的表格如下所示:

c_calcvalue c_parentID c_calcType
1000 5 None
250 5 calcCorrection

奇怪的是,如果说 WHERE c_ParentID = 5 AND c_calcType = 'calcCorrection' 我得到了 -250,或者如果我在 THEN 表达式中说 (THEN 0 else c_calcValue),总和也是正确的。

【问题讨论】:

  • 您应该尝试在 dbfiddle 中复制它。对于您提供的数据,结果应该是您所期望的。此外,您的查询引用了示例数据中没有的列。

标签: sql sql-server sum case


【解决方案1】:

我相信您的查询对于您显示的数据是正确的,但您可能有您不期望的数据。

拥有

CREATE TABLE DB_Calc (
  c_calcvalue int NOT NULL,
  c_calcType varchar(200) NOT NULL,
  PRIMARY KEY (c_calcvalue,c_calcType)
) 
INSERT INTO DB_Calc (c_calcvalue, c_calcType) VALUES
  (1000, 'None'),
  (250, 'calcCorrection');

以下选择

SELECT Sum(CASE WHEN c_calcType = 'calcCorrection' THEN (c_calcValue * -1)
                ELSE c_calcValue END) as c_calcValue
FROM DB_Calc

产生 750:

c_calcValue
750

小提琴here.

我同意 M.Ghandour 的观点,即您应该先验证源数据,然后再进行 SUM。

【讨论】:

  • 这里的结果相同,因为我们不知道完整的数据架构,但我相信问题出在 where 子句中,这可能会导致其他行意外。
  • 对不起,如果我不能显示真实的表格,我尝试了一切来重现这个但没有结果(添加空值或空值)只有当我说 THEN 0,我得到正确的值回来跨度>
【解决方案2】:

首先验证子查询并尝试该方法,

在选择求和之前尝试转换为数字:

SELECT (CASE
                 WHEN c_calcType = 'calcCorrection' THEN (CONVERT(c_calcValue, INT)  * -1)
                 ELSE CONVERT(c_calcValue, INT)
              END)
                AS c_calcValue,
             c_parentID
        FROM DB_Calc
       WHERE c_parentID IS NOT NULL AND c_state <> 'deactiveted'

如果有效,请尝试以下操作:

  SELECT SUM (cValTable.c_calcValue), cValTable.c_parentID
       FROM (SELECT (CASE
                 WHEN c_calcType = 'calcCorrection' THEN (CONVERT(c_calcValue, INT)* -1)
                 ELSE CONVERT(c_calcValue, INT)
              END)
                AS c_calcValue,
             c_parentID
        FROM DB_Calc
       WHERE c_parentID IS NOT NULL AND c_state <> 'deactiveted') cValTable
    GROUP BY cValTable.c_parentID

【讨论】:

  • 我验证了查询并且值都很好,如果手动计算所有负值,我得到我的 -250,但如果我尝试你的第二个查询,它仍然会减去 -500。我要疯了
  • 尝试像编辑后的答案@RekeUnhs那样转换为整数
【解决方案3】:

我不确定是什么原因造成的,但我的绕过结果只是现在将 calcCorrection 分成两个查询并使用 union all。

SELECT sum(c_calcValue),c_parentID FROM DBCalc WHERE r_Rechnungstyp <> 'calcCorrection' AND c_state <> 'deactiveted' GROUP BY c_parentID UNION ALL SELECT sum(-c_calcValue),c_parentID FROM DBCalc WHERE r_Rechnungstyp = 'calcCorrection' AND c_state <> 'deactiveted' GROUP BY c_parentID

【讨论】:

    猜你喜欢
    • 2020-07-14
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多