我有4张桌子,3张用于进钱,1张用于进钱
credittable1
uid | amnt | dat
1 | 50 |31-02-2016
2 | 40 |22-03-2017
...and so on
credittable2
uid | amnt | dat
1 | 60 |01-03-2016
2 | 20 |22-02-2017
...and so on
credittable3
uid | amnt | dat
1 | 70 |03-03-2016
2 | 10 |21-03-2017
...and so on
可借记
uid | amnt | dat
1 | 120 |12-04-2016
2 | 80 |25-02-2017
...and so on
我需要将所有4张表组合在一起,以看上去像是贷方和借方的帐簿以及该交易在每个用户按日期排序的余额。例如,我要打印uid 1的账簿,那么他的所有交易都应像账簿一样按信贷或借记交易发生的日期以及该交易的余额金额打印(就像银行存折一样) )。
所有表都非常繁琐,有大量记录,因此我正在寻找一种快速(性能良好)的解决方案。
最终实现需要在 Codeigniter 中完成。
用户可能在表1中获得10个(或任意数量)交易,依此类推在所有表中。每个表中每个用户的记录数可能会有所不同。
输出看起来像这样:
uid | date | credit | debit | balance amount
请提出实现此目标的方法。我无法决定是否应该使用Joins或其他策略来完成该操作。
答案 0 :(得分:1)
您可以union all
四个表,并取反debittable
中的金额:
SELECT uid, amt, dat FROM credittable1 UNION ALL
SELECT uid, amt, dat FROM credittable2 UNION ALL
SELECT uid, amt, dat FROM credittable3 UNION ALL
SELECT uid, -1 * amt, dat FROM debittable
答案 1 :(得分:0)
所有表上的UNION ALL
为您提供了基础(您应该考虑重新设计架构,从一开始就只使用一个这样的表)。
对于余额,可以使用子查询,该子查询获取“上一个”金额的总和。这里的“上一个”是指日期小于或等于当前预订日期的预订。由于一天中可能会有更多的预订,因此我们需要另一个标准来区分它们。这就是sno
发挥作用的地方-它也必须小于或等于当前值。为了确保sno
在整个集合中(而不只是它来自的表)是唯一的,我们会添加一个唯一的表标识符。
在MySQL 8.0中,可以使用窗口加总和来简化操作。但是我认为您使用的是次要版本。
SELECT x.amnt,
x.dat,
(SELECT coalesce(sum(amnt), 0)
FROM (SELECT concat('c1-', sno) sno
amnt,
dat
FROM credittable1
WHERE uid = 1
UNION ALL
SELECT concat('c3-', sno) sno,
amnt,
dat
FROM credittable2
WHERE uid = 1
UNION ALL
SELECT concat('c3-', sno) sno,
amnt,
dat
FROM credittable3
WHERE uid = 1
UNION ALL
SELECT concat('d1-', sno) sno,
-1 * amnt,
dat
FROM debittable
WHERE uid = 1) y
WHERE y.dat <= x.dat
AND y.sno <= x.sno) bal
FROM (SELECT concat('c1-', sno) sno,
amnt,
dat
FROM credittable1
WHERE uid = 1
UNION ALL
SELECT concat('c2-', sno) sno,
amnt,
dat
FROM credittable2
WHERE uid = 1
UNION ALL
SELECT concat('c3-', sno) sno,
amnt,
dat
FROM credittable3
WHERE uid = 1
UNION ALL
SELECT concat('d1-', sno) sno,
-1 * amnt,
dat
FROM debittable
WHERE uid = 1) x
ORDER BY x.dat;
答案 2 :(得分:0)
我想我会这样做以获得基本数据:
select uid, date, sum(credit) as credit, sum(debit) as debit
from ((select uid, dat amt as credit, 0 as debit
from credittable1
) union all
(select uid, dat amt as credit, 0 as debit
from credittable2
) union all
(select uid, dat amt as credit, 0 as debit
from credittable3
) union all
(select uid, dat, 0, - amt
from debittable
)
) ad
group by uid, dat
order by uid, date;
然后您可以使用变量获取余额:
select uid, date,
(@b := if(@u = uid, @u + credit + debit,
if(@u := uid, credit + debit, credit + debit)
)
) as balance
from (select uid, date, sum(credit) as credit, sum(debit) as debit
from ((select uid, dat amt as credit, 0 as debit
from credittable1
) union all
(select uid, dat amt as credit, 0 as debit
from credittable2
) union all
(select uid, dat amt as credit, 0 as debit
from credittable3
) union all
(select uid, dat, 0, - amt
from debittable
)
) ad
group by uid, date
order by uid, date
) ud cross join
(select @u := -1, @b := 0) balance;
或者在MySQL 8+中,您可以使用累积总和:
sum(debit + credit) over (partition by uid order by date)