我正在制作5张桌子的统计数据。我用一个客户数据制作了这个例子。
贷款
id | status
------------
1454 | payed
付款时间表
id | loan_id | user_client_id
-----------------------------
1456 | 1454 | 3113
payment_schedule_row
id | payment_schedule_id | payment | payment_date
---------------------------------------------------
5013 | 1456 | 32 | 2013-11-06
5014 | 1456 | 32 | 2013-12-06
5015 | 1456 | 32 | 2013-01-05
5016 | 1456 | 32 | 2013-02-04
5017 | 1456 | 32 | 2013-03-06
5018 | 1456 | 32 | 2013-04-05
5019 | 1456 | 32 | 2013-05-05
5020 | 1456 | 32 | 2013-06-04
5021 | 1456 | 32 | 2013-07-04
5022 | 1456 | 32 | 2013-08-03
5023 | 1456 | 32 | 2013-09-02
5014 | 1456 | 32 | 2013-10-02
payment_schedule_cover
id | payment_schedule_id | date | sum
----------------------------------------------
2282 | 1456 | 2013-11-08 | 34
3054 | 1456 | 2013-12-07 | 40
3776 | 1456 | 2013-01-04 | 38
4871 | 1456 | 2013-02-06 | 49
5954 | 1456 | 2013-03-06 | 40
7070 | 1456 | 2013-04-25 | 49
9029 | 1456 | 2013-05-21 | 52
10377 | 1456 | 2013-06-20 | 30
10391 | 1456 | 2013-06-21 | 30
10927 | 1456 | 2013-07-07 | 60
payment_schedule_delay
id | payment_schedule_row_id | start_date | end_date | delay
----------------------------------------------------------------
1135 | 5013 | 2013-11-07 | 2013-11-08 | 0.07
1548 | 5014 | 2013-12-07 | 2013-12-07 | 0.03
2628 | 5016 | 2014-02-05 | 2014-02-06 | 0.01
查询是:
SELECT period, loan_sum, covers, delay
FROM
(SELECT MAX(EXTRACT(YEAR_MONTH FROM psc.date)) AS period,
(SELECT SUM(psr2.payment) FROM payment_schedule_row AS psr2 WHERE psr.payment_schedule_id = psr2.payment_schedule_id) AS loan_sum,
(SELECT SUM(psc2.sum) FROM payment_schedule_cover AS psc2 WHERE psc.payment_schedule_id = psc2.payment_schedule_id) AS covers,
(SELECT SUM(psd2.delay) FROM payment_schedule_delay AS psd2 WHERE psr.id = psd2.payment_schedule_row_id) AS delay
FROM loan
INNER JOIN payment_schedule AS ps ON ps.loan_id = loan.id
INNER JOIN payment_schedule_row AS psr ON psr.payment_schedule_id = ps.id
INNER JOIN payment_schedule_cover AS psc ON psc.payment_schedule_id = ps.id
WHERE loan.status = 'payed'
GROUP BY ps.id) AS sum_by_id
GROUP BY period
查询结果:
period | loan_sum | covers | delay
-----------------------------------
201407 | 384 | 422 | 0.07
除了延迟,一切都是正确的。它应该是0.11(0.07 + 0.03 + 0.01)
所以我一直试图在查询中找到错误。也许有人可以告诉我我做错了什么。
Sqlfiddle链接: http://sqlfiddle.com/#!2/21585/2
答案 0 :(得分:0)
SELECT period, loan_sum, covers, delay
FROM
(SELECT MAX(EXTRACT(YEAR_MONTH FROM psc.date)) AS period,
(SELECT SUM(psr2.payment) FROM payment_schedule_row AS psr2 WHERE psr.payment_schedule_id = psr2.payment_schedule_id) AS loan_sum,
(SELECT SUM(psc2.sum) FROM payment_schedule_cover AS psc2 WHERE psc.payment_schedule_id = psc2.payment_schedule_id) AS covers,
(SELECT SUM(psd2.delay) FROM payment_schedule_delay AS psd2 WHERE psr.id = psd2.payment_schedule_row_id) AS delay
FROM loan
INNER JOIN payment_schedule AS ps ON ps.loan_id = loan.id
INNER JOIN payment_schedule_row AS psr ON psr.payment_schedule_id = ps.id
INNER JOIN payment_schedule_cover AS psc ON psc.payment_schedule_id = ps.id
INNER JOIN payment_schedule_delay AS psd ON psr.id = psd.payment_schedule_row_id
WHERE loan.status = 'payed'
GROUP BY ps.id) AS sum_by_id
GROUP BY period
答案 1 :(得分:0)
SELECT period, loan_sum, covers, delay
FROM
(SELECT MAX(EXTRACT(YEAR_MONTH FROM psc.date)) AS period,
(SELECT SUM(psr2.payment) FROM payment_schedule_row AS psr2 WHERE psr.payment_schedule_id = psr2.payment_schedule_id) AS loan_sum,
(SELECT SUM(psc2.sum) FROM payment_schedule_cover AS psc2 WHERE psc.payment_schedule_id = psc2.payment_schedule_id) AS covers,
(SELECT SUM(psd2.delay) FROM payment_schedule_delay AS psd2 WHERE psr.id IN /* IN operator will allow for multiple values like psr.id IN (5013,5014,5016) */ psd2.payment_schedule_row_id) AS delay
FROM loan
INNER JOIN payment_schedule AS ps ON ps.loan_id = loan.id
INNER JOIN payment_schedule_row AS psr ON psr.payment_schedule_id = ps.id
INNER JOIN payment_schedule_cover AS psc ON psc.payment_schedule_id = ps.id
WHERE loan.status = 'paid'
GROUP BY ps.id) AS sum_by_id
GROUP BY period
在汇总延迟值的行中将=
更改为IN
。
答案 2 :(得分:0)
我终于从MySQL论坛得到了答案。解决问题的答案是:
......有问题...
子查询中的Group By运算符在相关的子子查询和中没有看到聚合。这些总和需要移出一个级别。
外部查询的Group By to group没有聚合;它只是作为一个Order By
像a,b,c sum(d)... group by a的查询可以返回b和c的任意结果,除非a和b之间存在严格的1:1关系,在您的子查询中看起来不太可能。
相关的子查询效率低下,正如您的两阶段连接所示;
delay
相关子查询未加入任何内容
所以将相关子查询逻辑移到FROM子句,加入delay
查询,修改Group By子句,我们就......
select psc.period, psc.sum, psr.payments, sum(psd.delay) as delay
from loan
join payment_schedule as ps on ps.loan_id = loan.id
join(
select payment_schedule_id, sum(payment) as payments
from payment_schedule_row
group by payment_schedule_id
) as psr on psr.payment_schedule_id = ps.id
join (
select payment_schedule_id, sum(sum) as sum, max( extract(year_month from date) ) as period
from payment_schedule_cover
group by payment_schedule_id
) psc on ps.id = psc.payment_schedule_id
join payment_schedule_row psr2 on ps.id = psr2.payment_schedule_id
join (
select payment_schedule_row_id, sum(delay) as delay
from payment_schedule_delay
group by payment_schedule_row_id
) as psd on psr2.id = psd.payment_schedule_row_id
where loan.status = 'payed'
group by psc.period, psc.sum, psr.payments;