请考虑以下情形:用户拥有一个或多个(银行)帐户。账户余额的历史变化在表格中进行跟踪。我希望在他的所有帐户中及时显示用户资金的历史记录。这些是表格定义:
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `accounts` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `balances` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`account_id` int(11) DEFAULT NULL,
`amount` int(11) DEFAULT NULL,
`created_at` date DEFAULT NULL,
PRIMARY KEY (`id`)
);
以下是一些示例数据:
INSERT INTO `users` (`id`, `name`)
VALUES
(1,'Bob');
INSERT INTO `accounts` (`id`, `user_id`)
VALUES
(1,1),
(2,1);
INSERT INTO `balances` (`id`, `account_id`, `amount`, `created_at`)
VALUES
(1,1,100, '2012-01-01'),
(2,1,150, '2012-01-02'),
(3,2,1000,'2012-01-04'),
(4,2,1100,'2012-01-08'),
(5,1,175, '2012-01-10');
用户每个帐户只允许一次存款/取款,因此created_at
值可视为唯一。
给定样本数据,我想写的查询结果应为:
|'2012-01-01'|100 |
|'2012-01-02'|150 |
|'2012-01-04'|1150|
|'2012-01-08'|1250|
|'2012-01-10'|1275|
计划如下:
我在制定第2步的条件时遇到了问题。
答案 0 :(得分:0)
我试过这个(用我的纯英语理解:);
SELECT b.created_at, Sum(amount) amount, u.id, u.name
FROM balances b
LEFT JOIN accounts a ON a.id=b.account_id
LEFT JOIN users u ON u.id=a.user_id
GROUP BY b.created_at
ORDER BY b.created_at
得到了这个结果;
created_at amount id name
2012-01-01 100 1 Bob
2012-01-02 150 1 Bob
2012-01-04 1000 1 Bob
2012-01-08 1100 1 Bob
2012-01-10 175 1 Bob
我认为你写的所有日期字段都是独立的。
答案 1 :(得分:0)
select user_id,created_at,sum(accAmount) from
(
select a.id account_id,a.user_id user_id, dt.created_at created_at,
( select amount from balances b3 where (b3.account_id=a.id)
and b3.created_at=
(select max(created_at) as lastAccDate from balances b
where b.created_at<=dt.created_at and b.account_id=a.id)
) AccAmount
from accounts a,
(select distinct created_at from balances) dt
) AccountAmounts
group by user_id,created_at
order by 2
答案 2 :(得分:0)
我不是一个大的MySQL用户,但我创建了一个适用于MS SQL Server的查询。它不是特别高效(3个子查询和一个独特的,嘘!),所以你可能想要考虑是否有更好的方法而不是简单地在单个查询中导出它。
SELECT
b.created_at,
SUM(b.amount),
(
SELECT SUM(acc_amt)
FROM
(
SELECT DISTINCT b2.account_id,
(
SELECT TOP 1 b3.amount
FROM balances AS b3
WHERE b3.account_id = b2.account_id
AND b3.created_at <= b.created_at
ORDER BY b3.created_at DESC
) AS acc_amt
FROM balances AS b2
WHERE b2.created_at <= b.created_at
) temp_bal
)
FROM
balances AS b
GROUP BY
b.created_at
要转换为MySQL,您需要删除 TOP 1 并在b3子查询中的'DESC'之后添加 LIMIT 1 ,然后修改直到MySQL为对语法感到满意。我会去看看我是否可以转换它。