【问题标题】:MySQL Complex ArithmeticMySQL 复杂算术
【发布时间】:2012-09-17 00:36:00
【问题描述】:

我有一个 MySQL 表,如下所示:

debts

--------------------------
owed_by | owed_to | amount
--------|---------|-------
Alice   | Bob     | 5
Bob     | Jane    | 10
Alice   | Jane    | 10
Jane    | Bob     | 5

是否可以在 MySQL 中编写一个查询来返回每个人所欠的总额?他们欠谁并不重要,我只想归还每个人和(欠的人总数 - 欠的人总数)

得到欠款很容易

SELECT `owed_by`, SUM(`amount`) as 'Total Debt'
FROM `debts`
GROUP BY `owed_by`
ORDER BY SUM(`amount`) DESC

但我不知道如何减去他们的欠款。

此外,作为一般规则,在 MySQL(如果可能)或 PHP 中执行这样的操作更好吗?

这是我的示例数据的 SQL Fiddle:http://sqlfiddle.com/#!2/dd7cf/1

【问题讨论】:

  • 语言不是很流利,但你不能抓住桌子的两个不同视图吗? ViewOwedViewOwes 每个都有名称列和金额列之一。在每一列中按名称独立汇总金额,然后从另一个中减去一个。
  • 我也不是最流利的,但我会看看意见
  • 我不知道官方是否规定在 MySQL 或 PHP 中执行此操作更好,但我一直认为在 MySQL 中执行此操作会更好,就像您尝试做的那样。

标签: mysql math logic


【解决方案1】:

你可以把两边结合起来:

select Person, sum(debt) as 'Total Debt'
from (
    select owed_by as 'Person', amount as 'debt'
    from debts
    union all
    select owed_to, -1*amount
    from debts
) as q
group by Person;

【讨论】:

    【解决方案2】:
    SELECT owed.owed_by, owed.amount - coalesce(owns.amount, 0) as `Total Debt`
    FROM (
            select owed_by, sum(amount) as amount
            from debts
            group by owed_by
        ) owed
        left join (
            select owed_to, sum(amount) as amount
            from debts
            group by owed_to
        ) owns on owed.owed_by = owns.owed_to
    ORDER BY `Total Debt` DESC
    

    【讨论】:

    • 这里的问题是您只查看存在于owed_by 列中的人。看这个例子:sqlfiddle.com/#!2/53a6d/1。未显示用户“Roger”,即使他的债务应该是 -20。
    • @Travesty3 我知道这确实是 OP 想要的。
    • 哦,我猜那是我当时的误解。恕我直言,我想把评论留在那里,以澄清其他偶然发现这篇文章的人。
    • 如果 MYSQL 实现了FULL 连接,这将是一个非常好的解决方案。
    • @Travesty3 当然。我就是这么理解的。也不太确定。
    【解决方案3】:
    SELECT od.person, od.amount - COALESCE(ow.amount, 0) AS balance  
    FROM (SELECT owed_to AS person, SUM(amount) AS amount FROM debts GROUP BY owed_to) od  
    LEFT OUTER JOIN (SELECT owed_by AS person, SUM(amount) AS amount FROM debts GROUP BY owed_by) ow  
    ON od.person = ow.person
    UNION  
    SELECT owed_by, SUM(amount) * (-1) FROM debts   
    WHERE owed_by NOT IN (SELECT DISTINCT owed_to FROM debts)   
    GROUP BY owed_by; 
    

    【讨论】:

    • 抱歉,刚刚更正。我只是不知道如何以小提琴支持的任何 SQL 格式进行外部联接
    • 外连接是“WHERE od.amount *= ow.amount”
    • @foampile:这种可怕的外连接语法 (*=) 仅适用于 SQL-Server,不适用于 MySQL。它无论如何都已弃用,应该避免。
    • 我认为它实际上也适用于 ORCL,我认为语法是 (*)= 或类似的东西。我更喜欢拼写“LEFT OUTER JOIN xyz ON...”
    • 在 Oracle 中类似于 od.amount = ow.amount (+)
    【解决方案4】:
    SELECT `owed_by`, SUM(`amount`) as 'Total Debt'.
    (select sum(amount) from debts d2 where d1.owed_by = d2.owed_to) as `Total Plus`
    FROM `debts` d1
    GROUP BY `owed_by`
    ORDER BY SUM(`amount`) DESC
    

    【讨论】:

    • 这会在第 1 行产生错误 #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '. (select sum(amount) from debts d2 where d1.owed_by = d2.owed_to) as Total Plu'
    • 天啊,我觉得自己很笨。这应该是第一行末尾的逗号,而不是句号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多