【问题标题】:Why do I get incorrect SUM in my MYSQL query joining two tables?为什么我在连接两个表的 MYSQL 查询中得到不正确的 SUM?
【发布时间】:2012-04-10 21:53:08
【问题描述】:

简单的工作查询,列出每种许可证类型的许可证数量:

查询:

SELECT
  COUNT(licenses.licenseID) AS total
FROM
  licenses
GROUP BY
  licenses.licensetypeID

结果:

total
=====
389
 14
  2
  5
  3
  1
  1

现在我想总结一下许可证的利润。表 transactions 包含来自 PayPal 的所有交易。我用mc_gross来总结。有时会有退款,所以mc_gross 是否定的,交易量多于许可证。

在我当前的数据库中,四个许可证被删除,因为交易被退还。

我的尝试:

SELECT
  COUNT(licenses.licenseID) AS total,
  SUM( transactions.mc_gross ) AS gross
FROM
  licenses
  LEFT JOIN transactions ON licenses.txn_id = transactions.txn_id
GROUP BY
  licenses.licensetypeID

结果:

393     9020.00
 14     NULL
  2     NULL
  5     NULL
  3     100.00
  1     NULL
  1     NULL

请注意,第一个许可证类型现在比第一个查询多了四个。由此我推断它正在计算事务表中的额外行。但我不明白为什么,因为我认为LEFT JOIN 会占用左表licenses 的所有行并连接到任何可用的transactions

阅读不同的连接,我无法理解它们以产生我想要的结果。

我是在做不正确的加入吗?还是我按错误的值分组?

请注意,我确实想列出所有许可证类型 - 即使它们的总数为零。

(如果需要整个表格结构,请告诉我 - 我跳过它以避免使问题过长。我希望包括所有相关信息。)

【问题讨论】:

  • 尝试计数(distinct license.licenseid) 以避免重复计数
  • @Jason:这更正了我的计数。但现在我看到了另一个问题。总利润也是错误的。但这是由于@StilesCrisis 提到的,有时会出现重复的txn_id,因为他们的付款一直在等待中。看来我需要过滤掉这些。

标签: mysql


【解决方案1】:

可能有多个事务具有相同的TXN_ID。在这种情况下,连接将在每个匹配的事务中列出一次相同的许可证。

【讨论】:

  • 啊,是的。看着数据。有时会记录交易,但它正在等待处理。在这些情况下,将发生具有相同txn_id 的第二个事务。这就是它的原因。
【解决方案2】:

如果退款在交易表中输入为负数,则不应删除原始交易。两者都需要在场才能使总余额为 0。由于您看到的交易比您想象的多 4 笔,并且您知道有 4 笔退款,我会说原始交易和退款交易都在交易表中,因为他们应该是。

【讨论】:

  • 你是对的,这不是我的退款。它是重复的txn_id 条目,因为偶尔的待付款会导致具有相同txn_id 的重复交易条目。我现在根据@StilesCrisis 的评论看到了这一点。
  • 如果我是正确的,但您在退款时有真正的重复,而不是每个许可证的多个交易,那么您的非显着计数将大于(许可证计数 + 退款计数)。
【解决方案3】:

感谢我得到的 cmets,我设法创建了一个产生正确结果的查询:

SELECT
  COUNT( distinct licenses.licenseID ) AS total,
  SUM( temp.mc_gross / temp.quantity ) AS gross
FROM
  licenses
  LEFT JOIN
    ( SELECT txn_id, mc_gross, quantity
      FROM transactions
      WHERE valid = 'VERIFIED-PAID'
    ) AS temp ON licenses.txn_id = temp.txn_id
GROUP BY
  licenses.licensetypeID

正确数据:

total   gross
===================
389     7780.000000
 14     NULL
  2     NULL
  5     NULL
  3     60.000000
  1     NULL
  1     NULL

更新 - 改进的查询:

SELECT
  COUNT( licenses.licenseID ) AS total,
  SUM( transactions.mc_gross / transactions.quantity ) AS gross
FROM
  licenses
  LEFT JOIN transactions ON licenses.txn_id = transactions.txn_id AND transactions.valid = 'VERIFIED-PAID'
GROUP BY
  licenses.licensetypeID

【讨论】:

  • 我认为你可以在JOINON 子句中检查valid = 'VERIFIED-PAID'
  • @StilesCrisis:是的!确实如此!不知道你能做到这一点。更简单,更容易阅读。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 2013-02-24
  • 1970-01-01
  • 2014-11-07
  • 2015-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多