【问题标题】:MySql Query Credits And Debits From Same TableMySql从同一张表中查询贷方和借方
【发布时间】:2017-05-16 13:26:25
【问题描述】:

我有一个 MySql 表来控制借方和贷方。它看起来像这样

id | status | type  | amount | value | expiration | parent_id | company_id |
---|--------|------ |--------|-------|------------|-----------|------------|
1  |    1   |credit | 46     | 42.00 | 2018-04-01 | 0         | 1          |
2  |    1   |credit | 33     | 194.00| 2017-07-07 | 0         | 1          |
3  |    1   |credit | 49     | 17.00 | 2016-11-11 | 0         | 1          |
4  |    1   |debit  | 1      | NULL  | NULL       | 1         | 1          |
5  |    1   |debit  | 1      | NULL  | NULL       | 1         | 1          |
6  |    1   |debit  | 1      | NULL  | NULL       | 2         | 1          |
7  |    1   |debit  | 1      | NULL  | NULL       | 2         | 1          |
8  |    1   |debit  | 1      | NULL  | NULL       | 2         | 1          |
9  |    1   |debit  | 1      | NULL  | NULL       | 2         | 1          |
10 |    1   |debit  | 1      | NULL  | NULL       | 3         | 1          |

我想检索一个人现在有多少学分。

将所有状态 = 1 的借方与状态 = 1 且到期的每个父贷方相加 > NOW()

然后从它的父信用中减去

在这种情况下,我应该得到类似的东西

总积分 = (46 - 2) + (33 - 4)

到目前为止我得到的是

SELECT SUM(amount) as tot_debit 
FROM credits
WHERE company_id = 1 
      AND status = 1 
      AND type = 'debit' 
      AND parent_id IN (SELECT id
                         FROM credits 
                         WHERE company_id = 1 
                           AND status = 1 
                           AND expiration > NOW() 
                           AND type = 'credit') 
GROUP BY parent_id

关于如何让它发挥作用的任何想法?

谢谢

【问题讨论】:

    标签: php mysql sql


    【解决方案1】:

    您可以使用 correlation 来获得预期的结果:

    SELECT SUM(amount) 
           -
           COALESCE((SELECT SUM(amount)
                     FROM credits AS c2
                     WHERE company_id = 1 AND status = 1 AND 
                           type = 'debit' AND
                           c2.parent_id = c1.id), 0)
    FROM credits AS c1
    WHERE company_id = 1 AND status = 1 AND 
          type = 'credit' AND expiration > NOW();
    

    Demo here

    【讨论】:

    • 它几乎起作用了,但我通过将数量和合并结果相加进行了一些调整,它就像一个魅力!谢谢
    【解决方案2】:

    您应该使用自左连接,以便每条记录都与其父记录匹配(如果存在)并过滤掉过期记录。然后使用有条件的总和,您可以添加贷方并减去借方。

    SELECT  SUM(CASE WHEN type = 'credit' THEN amount ELSE amount * -1 END) AS total
    FROM    credits t1
    LEFT JOIN
            credits t2
    ON      t1.parent_id = t2.id AND
            t2.expiration > NOW()
    WHERE   t1.company_id = 1 AND 
            t1.status = 1 AND
            t1.expiration > NOW()
    

    【讨论】:

      【解决方案3】:

      由于您在一张表中同时拥有贷方和借方(我不会推荐这种设计),因此这里最快的方法可能是聚合:

      select sum(total)
      from
      (
        select 
          sum(case when type = 'credit' then value else -value end) as total
        from mytable
        where company_id = 1
        and status = 1
        group by case when type = 'credit' then id else parent_id end -- group by credit ID
        having sum(type = 'credit' and expiration > now()) > 0
      ) total_per_credit;
      

      HAVING 子句在 MySQL 中使用 true = 1 / false = 0。 (在其他 DBMS 中,您将使用 CASE 构造。)

      【讨论】:

      • 您是否愿意分享您的意见,以便更好地设计我的架构?
      • 很简单:贷方与借方引用贷方不同。所以我会制作这两个表:credit(credit_id, company_id, status, amount, value, expiration) 和 debit(debit_id, company_id, credit_id, status, amount)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-12
      相关资源
      最近更新 更多