在 Postgresql 中,如何使用具有多个条件的连接,包括 >= 和 <=
In Postgresql, how do I use joins with multiple conditions including >= and <=
我有 table A 和 table B。table A 中的每一行代表用户每次发送消息的时间。 table B 中的每一行代表用户每次购买礼物。
目标:对于用户每次发送消息,计算他们在发送消息时间戳之前的 7 天内购买了多少礼物。有些用户从不发送消息,有些用户从不购买礼物。如果tableA中的用户在7天内没有购买过礼物,则计数应为0。
Table答:
user_id
time
12345
2021-09-04 09:43:55
12345
2021-09-03 00:39:30
12345
2021-09-02 03:26:07
12345
2021-09-05 15:48:34
23456
2021-09-09 09:06:22
23456
2021-09-08 08:06:21
00001
2021-09-03 15:38:15
00002
2021-09-03 15:38:15
Table乙:
user_id
time
12345
2021-09-01 09:43:55
12345
2021-08-03 00:42:30
12345
2021-09-03 02:16:07
00003
2021-09-05 15:48:34
23456
2021-09-03 09:06:22
23456
2021-09-10 08:06:21
预期输出:
user_id
time
count
12345
2021-09-04 09:43:55
2
12345
2021-09-03 00:39:30
1
12345
2021-09-02 03:26:07
1
12345
2021-09-05 15:48:34
2
23456
2021-09-09 09:06:22
1
23456
2021-09-08 08:06:21
1
00001
2021-09-03 15:38:15
0
00002
2021-09-03 15:38:15
0
我试过的查询:
SELECT A.user_id, A.time, coalesce(count(*), 0) as count
FROM A
LEFT JOIN B ON A.user_id = B.user_id AND B.time >= A.time - INTERVAL '7 days' AND B.time < A.time
GROUP BY 1,2
但是,返回的计数与预期结果不符,不确定我是否正确执行了连接和条件。
您需要计算可能为 NULL 的列中的值,即来自 table B 的值,以便获得不存在的匹配项的正确计数。即在 COUNT(*)
到 COUNT(b.column_from_b_table)
中更具体。请参阅下面的工作演示 fiddle 的修改:
SELECT
A.user_id,
A.time,
coalesce(count(B.user_id), 0) as count
FROM A
LEFT JOIN B ON A.user_id = B.user_id AND
B.time >= A.time - INTERVAL '7 days' AND
B.time < A.time
GROUP BY 1,2;
user_id
time
count
1
2021-09-03T15:38:15.000Z
0
12345
2021-09-05T15:48:34.000Z
2
23456
2021-09-08T08:06:21.000Z
1
12345
2021-09-04T09:43:55.000Z
2
12345
2021-09-03T00:39:30.000Z
1
23456
2021-09-09T09:06:22.000Z
1
2
2021-09-03T15:38:15.000Z
0
12345
2021-09-02T03:26:07.000Z
1
让我知道这是否适合你。
我有 table A 和 table B。table A 中的每一行代表用户每次发送消息的时间。 table B 中的每一行代表用户每次购买礼物。
目标:对于用户每次发送消息,计算他们在发送消息时间戳之前的 7 天内购买了多少礼物。有些用户从不发送消息,有些用户从不购买礼物。如果tableA中的用户在7天内没有购买过礼物,则计数应为0。
Table答:
user_id | time |
---|---|
12345 | 2021-09-04 09:43:55 |
12345 | 2021-09-03 00:39:30 |
12345 | 2021-09-02 03:26:07 |
12345 | 2021-09-05 15:48:34 |
23456 | 2021-09-09 09:06:22 |
23456 | 2021-09-08 08:06:21 |
00001 | 2021-09-03 15:38:15 |
00002 | 2021-09-03 15:38:15 |
Table乙:
user_id | time |
---|---|
12345 | 2021-09-01 09:43:55 |
12345 | 2021-08-03 00:42:30 |
12345 | 2021-09-03 02:16:07 |
00003 | 2021-09-05 15:48:34 |
23456 | 2021-09-03 09:06:22 |
23456 | 2021-09-10 08:06:21 |
预期输出:
user_id | time | count |
---|---|---|
12345 | 2021-09-04 09:43:55 | 2 |
12345 | 2021-09-03 00:39:30 | 1 |
12345 | 2021-09-02 03:26:07 | 1 |
12345 | 2021-09-05 15:48:34 | 2 |
23456 | 2021-09-09 09:06:22 | 1 |
23456 | 2021-09-08 08:06:21 | 1 |
00001 | 2021-09-03 15:38:15 | 0 |
00002 | 2021-09-03 15:38:15 | 0 |
我试过的查询:
SELECT A.user_id, A.time, coalesce(count(*), 0) as count
FROM A
LEFT JOIN B ON A.user_id = B.user_id AND B.time >= A.time - INTERVAL '7 days' AND B.time < A.time
GROUP BY 1,2
但是,返回的计数与预期结果不符,不确定我是否正确执行了连接和条件。
您需要计算可能为 NULL 的列中的值,即来自 table B 的值,以便获得不存在的匹配项的正确计数。即在 COUNT(*)
到 COUNT(b.column_from_b_table)
中更具体。请参阅下面的工作演示 fiddle 的修改:
SELECT
A.user_id,
A.time,
coalesce(count(B.user_id), 0) as count
FROM A
LEFT JOIN B ON A.user_id = B.user_id AND
B.time >= A.time - INTERVAL '7 days' AND
B.time < A.time
GROUP BY 1,2;
user_id | time | count |
---|---|---|
1 | 2021-09-03T15:38:15.000Z | 0 |
12345 | 2021-09-05T15:48:34.000Z | 2 |
23456 | 2021-09-08T08:06:21.000Z | 1 |
12345 | 2021-09-04T09:43:55.000Z | 2 |
12345 | 2021-09-03T00:39:30.000Z | 1 |
23456 | 2021-09-09T09:06:22.000Z | 1 |
2 | 2021-09-03T15:38:15.000Z | 0 |
12345 | 2021-09-02T03:26:07.000Z | 1 |
让我知道这是否适合你。