3

很抱歉这个真正简单的问题,我刚刚学习 PHP 和 MySQL,我已经在谷歌上搜索了一个多星期,但我没有找到任何答案。

我创建了一个简单的财务脚本,表格如下:

table_a
aid | value
1   | 100
2   | 50
3   | 150

table_b
bid | aid | value
1   | 1   | 10
2   | 1   | 15
3   | 2   | 5
4   | 2   | 10
5   | 3   | 25
6   | 3   | 40

我想要这样的结果

No | ID | Total | Balance
1  | 1  | 10    | 90
2  | 1  | 25    | 75
3  | 2  | 5     | 45
4  | 2  | 15    | 35
5  | 3  | 25    | 125
6  | 3  | 65    | 85

有人可以帮我解决我的问题吗?

谢谢

4

3 回答 3

2

试试这个运行总数:http ://www.sqlfiddle.com/#!2/ce765/1

select  
    bid as no, value,
    @rt := if(aid = @last_id, @rt + value, value) as total,
    @last_id := aid
from table_b b, (select @rt := 0 as x, @last_id := null) as vars
order by b.bid, b.aid;

输出:

| NO | VALUE | TOTAL | @LAST_ID := AID |
|----|-------|-------|-----------------|
|  1 |    10 |    10 |               1 |
|  2 |    15 |    25 |               1 |
|  3 |     5 |     5 |               2 |
|  4 |    10 |    15 |               2 |
|  5 |    25 |    25 |               3 |
|  6 |    40 |    65 |               3 |

然后加入表A,最终查询:

select x.no, x.aid, x.value, x.total, a.value - x.total as balance
from
(
  select    
    bid as no, aid, value,
    @rt := if(aid = @last_id, @rt + value, value) as total,
    @last_id := aid
  from table_b b, (select @rt := 0 as x, @last_id := null) as vars
  order by b.bid, b.aid
) as x
join table_a a using(aid)

输出:

| NO | AID | VALUE | TOTAL | BALANCE |
|----|-----|-------|-------|---------|
|  1 |   1 |    10 |    10 |      90 |
|  2 |   1 |    15 |    25 |      75 |
|  3 |   2 |     5 |     5 |      45 |
|  4 |   2 |    10 |    15 |      35 |
|  5 |   3 |    25 |    25 |     125 |
|  6 |   3 |    40 |    65 |      85 |

现场测试:http ://www.sqlfiddle.com/#!2/ce765/1


更新

不依赖于列出排序,分组运行总计不会受到影响:http ://www.sqlfiddle.com/#!2/6a1e6/3

select x.no, x.aid, x.value, x.total, a.value - x.total as balance
from
(
  select    
    @rn := @rn + 1 as no, aid, value,
    @rt := if(aid = @last_id, @rt + value, value) as total,
    @last_id := aid
  from table_b b, (select @rt := 0 as x, @last_id := null, @rn := 0) as vars
  order by b.aid, b.bid
) as x
join table_a a using(aid)

输出:

| NO | AID | VALUE | TOTAL | BALANCE |
|----|-----|-------|-------|---------|
|  1 |   1 |    10 |    10 |      90 |
|  2 |   1 |    15 |    25 |      75 |
|  3 |   1 |     7 |    32 |      68 |
|  4 |   2 |     5 |     5 |      45 |
|  5 |   2 |    10 |    15 |      35 |
|  6 |   3 |    25 |    25 |     125 |
|  7 |   3 |    40 |    65 |      85 |

现场测试:http ://www.sqlfiddle.com/#!2/6a1e6/3

于 2012-06-03T10:59:21.963 回答
1
SELECT
   tb.bid as No,
   ta.aid as ID,
   tb.value as Total,
   ta.value-tb.total as Balance
FROM
  table_a AS ta
  INNER JOIN (
    SELECT
      tbx.aid AS aid,
      tbx.bid AS bid,
      tbx.value AS value,
      SUM(tby.value) AS total
    FROM 
      table_b AS tbx
      INNER JOIN table_b AS tby ON tby.aid=tbx.aid AND tby.bid<=tbx.bid
    GROUP BY tbx.bid
    ORDER BY tbx.bid
  ) AS tb ON tb.aid=ta.aid
ORDER BY tb.bid

正如@Quassnoi 指出的那样,这对于 MySQL 来说不是很有效。我尝试使用异常连接而不是子查询,因为内部查询本身可能有用。

编辑

对此产生了一些兴趣,发现连接版本的速度是@Quassnoi 的子查询版本的两倍……有人知道为什么会这样吗?

编辑

回答第二个问题(在下面的评论中):

SELECT
  table_a.aid AS aid,
  SUM(table_b.value) AS Total,
  table_a.value-SUM(table_b.value) AS Balance
FROM
  table_a
  INNER JOIN table_b ON table_a.aid=table_b.aid
GROUP BY table_a.aid
于 2012-06-03T10:30:15.153 回答
0

您正在寻找分析功能。不幸的是,MySQL缺少它们。

您可以以一种效率较低的方式实现它:

SELECT  bid, aid, total, value - total
FROM    (
        SELECT  b.bid, b.aid, COALESCE(a.value, 0) AS value,
                (
                SELECT  SUM(value)
                FROM    b bp
                WHERE   bp.aid = b.aid
                        AND bp.bid <= b.bid
                ) AS total
        FROM    b
        LEFT JOIN
                a
        ON      a.aid = b.aid
        ) q
于 2012-06-03T10:21:25.440 回答