加入并聚合右边的日期 table <= 左边的日期 table
Join and aggregate where date in right table <= date in left table
假设我有一个 table 有两列 - customer_id
和 date
:
customer_id date
1 2020-01-29
1 2020-03-14
2 2020-04-05
2 2020-02-18
我有另一个 table 显示客户购买的日期和金额:
customer_id date amount
1 2019-12-03 10
1 2020-01-30 20
1 2020-03-10 30
1 2020-03-18 40
2 2020-02-29 50
2 2020-03-10 60
2 2020-04-01 70
我现在想在第一个 table 和第二个 table 上创建一个新列,显示第一个 [= 的每一行上迄今为止购买金额的总和=28=]:
customer_id date amount_td
1 2020-01-29 10
1 2020-03-14 60
2 2020-04-05 180
2 2020-03-20 110
我该怎么做?我对逻辑的最初想法是这样的:
SELECT
table1.customer_id,
table1.date,
table2_agg as amount_td
FROM
table1
LEFT JOIN (
SELECT
customer_id,
SUM(amount)
FROM
table2
HAVING
table2.date <= table1.date
) table2_agg
ON
table1.customer_id = table2_agg.customer_id
当然,这在句法和逻辑上并不完全存在。
由于需要根据 table1
中的 date
在 table2
中进行聚合,这可能比 JOIN
更容易编写为相关子查询:
SELECT
table1.customer_id,
table1.date,
COALESCE((SELECT SUM(amount) AS amount
FROM table2
WHERE table2.date <= table1.date AND
table2.customer_id = table1.customer_id), 0) AS amount
FROM
table1
或者您可以将其写成 JOIN
,但聚合需要发生在查询的顶层:
SELECT
table1.customer_id,
table1.date,
COALESCE(SUM(table2.amount), 0) AS amount
FROM
table1
LEFT JOIN
table2 ON table2.customer_id = table1.customer_id
AND table2.date <= table1.date
GROUP BY table1.customer_id, table1.date
无论哪种情况,输出都是:
customer_id date amount
1 2020-01-29 10
1 2020-03-14 60
2 2020-04-05 180
2 2020-03-20 110
如果您的(未公开的)DBMS 支持横向连接,您可以这样做:
select t1.*, t.amount
from table1 t1
left join lateral (
select t2.customer_id, sum(t2.amount) as amount
from table2 t2
where t2.customer_id = t1.customer_id
and t2.date <= t1.date
group by t2.customer_id
) as t on true
假设我有一个 table 有两列 - customer_id
和 date
:
customer_id date
1 2020-01-29
1 2020-03-14
2 2020-04-05
2 2020-02-18
我有另一个 table 显示客户购买的日期和金额:
customer_id date amount
1 2019-12-03 10
1 2020-01-30 20
1 2020-03-10 30
1 2020-03-18 40
2 2020-02-29 50
2 2020-03-10 60
2 2020-04-01 70
我现在想在第一个 table 和第二个 table 上创建一个新列,显示第一个 [= 的每一行上迄今为止购买金额的总和=28=]:
customer_id date amount_td
1 2020-01-29 10
1 2020-03-14 60
2 2020-04-05 180
2 2020-03-20 110
我该怎么做?我对逻辑的最初想法是这样的:
SELECT
table1.customer_id,
table1.date,
table2_agg as amount_td
FROM
table1
LEFT JOIN (
SELECT
customer_id,
SUM(amount)
FROM
table2
HAVING
table2.date <= table1.date
) table2_agg
ON
table1.customer_id = table2_agg.customer_id
当然,这在句法和逻辑上并不完全存在。
由于需要根据 table1
中的 date
在 table2
中进行聚合,这可能比 JOIN
更容易编写为相关子查询:
SELECT
table1.customer_id,
table1.date,
COALESCE((SELECT SUM(amount) AS amount
FROM table2
WHERE table2.date <= table1.date AND
table2.customer_id = table1.customer_id), 0) AS amount
FROM
table1
或者您可以将其写成 JOIN
,但聚合需要发生在查询的顶层:
SELECT
table1.customer_id,
table1.date,
COALESCE(SUM(table2.amount), 0) AS amount
FROM
table1
LEFT JOIN
table2 ON table2.customer_id = table1.customer_id
AND table2.date <= table1.date
GROUP BY table1.customer_id, table1.date
无论哪种情况,输出都是:
customer_id date amount
1 2020-01-29 10
1 2020-03-14 60
2 2020-04-05 180
2 2020-03-20 110
如果您的(未公开的)DBMS 支持横向连接,您可以这样做:
select t1.*, t.amount
from table1 t1
left join lateral (
select t2.customer_id, sum(t2.amount) as amount
from table2 t2
where t2.customer_id = t1.customer_id
and t2.date <= t1.date
group by t2.customer_id
) as t on true