多个用户的左外连接
Left outer join for multiple users
我有一个高尔夫球回合的数据库。我想看看去年每个用户每个月有多少回合。
为此,我使用此代码
创建了此视图 last_12_months
SELECT date_part('month'::text, dates.date) AS month,
date_part('year'::text, dates.date) AS year
FROM ( SELECT (generate_series((now() - '1 year'::interval), now(), '1 mon'::interval))::date AS date) dates;
month
year
1
2020
2
2020
and so on to ...
12
2020
统计轮次的汇总视图也很简单rounds_count_by_users
user_id
month
year
count_all
1
1
2020
15
1
3
2020
12
1
5
2020
10
2
4
2020
7
2
8
2020
6
2
9
2020
3
现在,对于我想要的,使用 left outer join
查询每个用户非常简单
select *
from last_12_months
left outer join rounds_count_by_users
on last_12_months.month = rounds_count_by_users.month
and last_12_months.year = rounds_count_by_users.year
and user_id = 1
这给了我所有的月份,即使用户没有玩过几轮。然而,我想要的是能够为每个用户执行此操作,并制作一个物化视图以便于查询。有没有一种简单易行的方法来做到这一点?要清楚这是我想要的最终 table。
这个查询至少不起作用,就我所知。
select *
from last_12_months
left outer join rounds_count_by_users
on last_12_months.month = rounds_count_by_users.month
and last_12_months.year = rounds_count_by_users.year
where user_id = 1
user_id
month
year
count_all
1
1
2020
15
1
2
2020
null
1
3
2020
12
1
4
2020
null
1
5
2020
10
1
6
2020
null
1
7
2020
null
1
8
2020
null
1
9
2020
null
1
10
2020
null
1
11
2020
null
1
12
2020
null
2
1
2020
null
2
2
2020
null
2
3
2020
null
2
4
2020
7
2
5
2020
null
2
6
2020
null
2
7
2020
null
2
8
2020
6
2
9
2020
3
2
10
2020
null
2
11
2020
null
2
12
2020
null
我为此做了一个 SQL Fiddle(值略有不同,但架构相同)
PS:我知道 table 别名和数据建模等等。我的问题完全是关于如何实现最终结果。
这个查询:
select * from last_12_months
where (year = year(current_date) - 1 and month >= month(current_date))
or
(year = year(current_date) and month < month(current_date))
returns 最近 12 个月(不包括当前月份)last_12_months
的行。
这个查询:
select distinct user_id from rounds_count_by_users
returns 所有不同的 user_id
(如果这些 ID 存储在 users
table 中会更好)。
您必须 CROSS
加入上述查询,然后 LEFT
加入 rounds_count_by_users
:
select u.user_id, m.month, m.year, r.count_all
from (
select * from last_12_months
where (year = year(current_date) - 1 and month >= month(current_date))
or
(year = year(current_date) and month < month(current_date))
) m cross join (select distinct user_id from rounds_count_by_users) u
left outer join rounds_count_by_users r
on m.month = r.month and m.year = r.year and u.user_id = r.user_id
order by u.user_id, m.month
参见demo。
所以我在评论中提供帮助后设法做到了这一点。
这让我得到了我想要的。
with all_rows as (
select * from view_last_12_months inner join users on true
)
select id as user_id, all_rows.year, all_rows.month, count_all
from all_rows left outer join view_rounds_count_last_year last12
on last12.month = all_rows.month
and last12.year = all_rows.year
and all_rows.id = last12.user_id
我有一个高尔夫球回合的数据库。我想看看去年每个用户每个月有多少回合。
为此,我使用此代码
创建了此视图last_12_months
SELECT date_part('month'::text, dates.date) AS month,
date_part('year'::text, dates.date) AS year
FROM ( SELECT (generate_series((now() - '1 year'::interval), now(), '1 mon'::interval))::date AS date) dates;
month | year |
---|---|
1 | 2020 |
2 | 2020 |
and so on to ... | |
12 | 2020 |
统计轮次的汇总视图也很简单rounds_count_by_users
user_id | month | year | count_all |
---|---|---|---|
1 | 1 | 2020 | 15 |
1 | 3 | 2020 | 12 |
1 | 5 | 2020 | 10 |
2 | 4 | 2020 | 7 |
2 | 8 | 2020 | 6 |
2 | 9 | 2020 | 3 |
现在,对于我想要的,使用 left outer join
查询每个用户非常简单
select *
from last_12_months
left outer join rounds_count_by_users
on last_12_months.month = rounds_count_by_users.month
and last_12_months.year = rounds_count_by_users.year
and user_id = 1
这给了我所有的月份,即使用户没有玩过几轮。然而,我想要的是能够为每个用户执行此操作,并制作一个物化视图以便于查询。有没有一种简单易行的方法来做到这一点?要清楚这是我想要的最终 table。
这个查询至少不起作用,就我所知。
select *
from last_12_months
left outer join rounds_count_by_users
on last_12_months.month = rounds_count_by_users.month
and last_12_months.year = rounds_count_by_users.year
where user_id = 1
user_id | month | year | count_all |
---|---|---|---|
1 | 1 | 2020 | 15 |
1 | 2 | 2020 | null |
1 | 3 | 2020 | 12 |
1 | 4 | 2020 | null |
1 | 5 | 2020 | 10 |
1 | 6 | 2020 | null |
1 | 7 | 2020 | null |
1 | 8 | 2020 | null |
1 | 9 | 2020 | null |
1 | 10 | 2020 | null |
1 | 11 | 2020 | null |
1 | 12 | 2020 | null |
2 | 1 | 2020 | null |
2 | 2 | 2020 | null |
2 | 3 | 2020 | null |
2 | 4 | 2020 | 7 |
2 | 5 | 2020 | null |
2 | 6 | 2020 | null |
2 | 7 | 2020 | null |
2 | 8 | 2020 | 6 |
2 | 9 | 2020 | 3 |
2 | 10 | 2020 | null |
2 | 11 | 2020 | null |
2 | 12 | 2020 | null |
我为此做了一个 SQL Fiddle(值略有不同,但架构相同)
PS:我知道 table 别名和数据建模等等。我的问题完全是关于如何实现最终结果。
这个查询:
select * from last_12_months
where (year = year(current_date) - 1 and month >= month(current_date))
or
(year = year(current_date) and month < month(current_date))
returns 最近 12 个月(不包括当前月份)last_12_months
的行。
这个查询:
select distinct user_id from rounds_count_by_users
returns 所有不同的 user_id
(如果这些 ID 存储在 users
table 中会更好)。
您必须 CROSS
加入上述查询,然后 LEFT
加入 rounds_count_by_users
:
select u.user_id, m.month, m.year, r.count_all
from (
select * from last_12_months
where (year = year(current_date) - 1 and month >= month(current_date))
or
(year = year(current_date) and month < month(current_date))
) m cross join (select distinct user_id from rounds_count_by_users) u
left outer join rounds_count_by_users r
on m.month = r.month and m.year = r.year and u.user_id = r.user_id
order by u.user_id, m.month
参见demo。
所以我在评论中提供帮助后设法做到了这一点。 这让我得到了我想要的。
with all_rows as (
select * from view_last_12_months inner join users on true
)
select id as user_id, all_rows.year, all_rows.month, count_all
from all_rows left outer join view_rounds_count_last_year last12
on last12.month = all_rows.month
and last12.year = all_rows.year
and all_rows.id = last12.user_id