(MySQL)融合&按期间总计两张表

时间:2017-11-02 15:06:06

标签: mysql merge

我有两张桌子。

+----+------------+------------+
| id | pay_date   | payment    | 
+----+------------+------------+
|  1 | 2010-01-01 | 20000      |
|  1 | 2010-01-02 | 30000      |
|  1 | 2010-01-03 | 30000      |
|  1 | 2010-01-06 | 40000      |
|  2 | 2010-01-01 | 10000      |
|  2 | 2010-01-03 | 30000      |
|  2 | 2010-01-06 | 70000      |
+----+------------+------------+


+----+------------+------------+
| id | start_date | end_date   |
+----+------------+------------+
|  1 | 2010-01-01 | 2010-01-05 |
|  1 | 2010-01-06 | 2010-01-30 |
|  2 | 2010-01-01 | 2010-01-05 |
|  2 | 2010-01-06 | 2010-01-10 |
+----+------------+------------+

通过汇总我想在桌子下面制作的两个表格。

+----+------------+------------+------------+
| id | start_date | end_date   | payment    |
+----+------------+------------+------------+
|  1 | 2010-01-01 | 2010-01-05 | 80000      |
|  1 | 2010-01-06 | 2010-01-30 | 40000      |
|  2 | 2010-01-01 | 2010-01-05 | 40000      |
|  2 | 2010-01-06 | 2010-01-10 | 70000      |
+----+------------+------------+------------+

此表是固定期间内的相同ID的付款总和。

如何制作此表?

2 个答案:

答案 0 :(得分:1)

对于您提供给我们的确切数据,我们可以将第二个表连接到第一个表,条件是付款日期在第一个表中的开始日期和结束日期之间,并且id值比赛。但是这里有一个明显的边缘案例问题。如果支付日期恰好与第二个表中的开始日期和结束日期重叠,会发生什么?然后我们不清楚我们应该分配该付款的范围。如果我们只使用BETWEEN,我们最终会重复计算付款。

因此,在下面的查询中,我假设如果支付日期大于或等于开始日期,则会被分配,但严格地小于结束日期。这可能不是您想要的逻辑,但如果您有重叠数据,您可能会做出类似的假设。

SELECT
    t2.id, t2.start_date, t2.end_date, SUM(t1.payment) AS payment
FROM table2 t2
LEFT JOIN table1 t1
    ON t1.id = t2.id AND
       t1.pay_date >= t2.start_date AND
       t1.pay_date < t2.end_date
GROUP BY
    t2.id, t2.start_date, t2.end_date
ORDER BY
    t2.id, t2.start_date;

<强>输出:

enter image description here

在这里演示:

Rextester

答案 1 :(得分:0)

总结另一个表格中paymentpay_date之间start_dateend_date

<强>查询

select t1.`id`, t1.`start_date`, t1.`end_date`,
sum(t2.`payment`) as `payment`
from `table2` as t1
join `table1` as t2
on t1.`id` = t2.`id`
and t2.`pay_date` between t1.`start_date` and t1.`end_date`
group by t1.`id`, t1.`start_date`, t1.`end_date`;