2

我有一张下表用于应付

在此处输入图像描述

设想:

We are going to pay 6000 to our vendor, this payment apply on 2nd row and remaining 2500 apply on 3rd row. after apply the 2500 on 3rd row , there will be a remaining balance of 1000.

Now I want to write a query that return number of rows base on payment enter. The conditions of query are as follow:

  1. 检查余额大于0
  2. 仅返回付款适用的行。i.e. In above scenario, payment was 6000, and then query check that in which 6000 apply, base upon that decision it should return rows. In 6000 case he should return 2nd and 3rd row, if payment = 8000 then query will return 3 row because 7000 satisfy/ clear 2nd & 3rd payable and remaining 1000 will reduce the balance of 4th entry.

我想要一个只返回付款适用的行数的查询?

让我知道 !

4

1 回答 1

3

考虑到 order by 的请求duedate,并且要知道“剩余”多少,您会得到以下内容。此查询将为您提供付款中的剩余金额left以及减去(剩余的)付款后的余额new_balance

SELECT p.*,
    IF(balance < @left, 0, balance - @left) AS 'new_balance',
    @left := IF(balance > @left, 0, @left - balance) AS 'left'
  FROM (
    SELECT * FROM payable
      WHERE balance > 0
      ORDER BY duedate, payableid
    ) AS p
  JOIN (SELECT @left := 6000) AS r ON @left > 0

SQL Fiddle中的上述查询

一些注意事项:

  • 由于duedate不是唯一的,我也添加了payableid(我认为它是唯一的)。为了保持一致性ORDER BY,子查询中的 forp 必须是唯一的。
  • 子查询返回的结果必须只包含可以贷记金额的记录。
    (因此,如果您有一个account_id列或类似的列,则将其包含WHERE在子查询中)。
  • 为了优化起见,子查询返回的结果应该尽可能小
    (因此我们放置WHERE balance > 0在子查询中而不是外部查询中)。
  • 如果您想知道“为什么是子查询?”:因为在选择ORDER BY执行。因此,如果我们不使用子查询,将被错误地应用并且将变得无用。@leftORDER BY
于 2013-08-27T20:10:01.903 回答