如何指望 join a table with 2 conditions?
How to count on join a table with 2 conditions?
我有一个items
table
id
name
1
Nganu
2
Kae
3
Lho
我还有一个item_usages
table:
id
item_id
user_id
usage_time
1
1
99
2021-10-07 00:00:00
2
2
99
2021-10-07 00:00:00
3
1
99
2021-10-08 00:00:00
4
1
22
2021-10-08 00:00:00
5
3
22
2021-10-08 00:00:00
6
1
99
2021-10-08 00:00:00
我想在查询中查找项目的总使用量和用户使用量。我想找到 user_id 99 用法的示例,预期结果:
id
name
total_usage
user_usage
2
Kae
1
1
1
Nganu
4
3
3
Lho
1
0
我试过了:
select
"items".*,
count(total_usage.id) as total_usage,
count(user_usage.id) as user_usage
from
"items"
left join
"item_usages" as "total_usage" on "items"."id" = "total_usage"."item_id"
left join
"item_usages" as "user_usage" on "user_usage"."item_id" = "items"."id"
and "user_usage"."user_id" = 99
group by
"items"."id";
但是 returns:
id
name
total_usage
user_usage
2
Kae
1
1
1
Nganu
12
12
3
Lho
1
0
item_usages
只有 6 行,为什么 Nganu 在两种用法上都有 12 行?如何修复我的查询?
我试过 PostgreSQL 12.8 和 13.4,我也在 SQLFiddle(PostgreSQL 9.6) 上测试过,这里是 link:
http://sqlfiddle.com/#!17/f1aac/5
我得到返回正确结果的查询:
select
"items".*,
min(total_usage.total_count) as total_usage,
count(user_usage.id) as user_usage
from "items"
left join
(select item_id,count(item_id) as total_count from item_usages group by item_id) as total_usage
on "items"."id" = "total_usage"."item_id"
left join "item_usages" as "user_usage"
on "user_usage"."item_id" = "items"."id" and "user_usage"."user_id" = 99
group by "items"."id";
但我不知道性能如何,所以如果可能的话我仍然会找到更快的查询并且仍然想知道:
为什么我的第一个查询给出了错误的结果?
您查询 returns 高数字的原因是您加入了 2 次。
(来自 Nganu 的一侧)第一个连接将产生 4 行,第二个连接将这 4 行与 3 行相同的 table 映射,产生 12 行。
您只需 1 个连接即可解决此问题:
select "items".id,
count(total_usage.id) as total_usage,
sum(case when total_usage.user_id = 99 then 1 else 0 end) as user_usage
from "items"
left join "item_usages" as "total_usage" on "items"."id" = "total_usage"."item_id"
group by "items".id
而且它应该工作得更快(尽管在小数据集上不可见)
我有一个items
table
id | name |
---|---|
1 | Nganu |
2 | Kae |
3 | Lho |
我还有一个item_usages
table:
id | item_id | user_id | usage_time | |
---|---|---|---|---|
1 | 1 | 99 | 2021-10-07 00:00:00 | |
2 | 2 | 99 | 2021-10-07 00:00:00 | |
3 | 1 | 99 | 2021-10-08 00:00:00 | |
4 | 1 | 22 | 2021-10-08 00:00:00 | |
5 | 3 | 22 | 2021-10-08 00:00:00 | |
6 | 1 | 99 | 2021-10-08 00:00:00 |
我想在查询中查找项目的总使用量和用户使用量。我想找到 user_id 99 用法的示例,预期结果:
id | name | total_usage | user_usage |
---|---|---|---|
2 | Kae | 1 | 1 |
1 | Nganu | 4 | 3 |
3 | Lho | 1 | 0 |
我试过了:
select
"items".*,
count(total_usage.id) as total_usage,
count(user_usage.id) as user_usage
from
"items"
left join
"item_usages" as "total_usage" on "items"."id" = "total_usage"."item_id"
left join
"item_usages" as "user_usage" on "user_usage"."item_id" = "items"."id"
and "user_usage"."user_id" = 99
group by
"items"."id";
但是 returns:
id | name | total_usage | user_usage |
---|---|---|---|
2 | Kae | 1 | 1 |
1 | Nganu | 12 | 12 |
3 | Lho | 1 | 0 |
item_usages
只有 6 行,为什么 Nganu 在两种用法上都有 12 行?如何修复我的查询?
我试过 PostgreSQL 12.8 和 13.4,我也在 SQLFiddle(PostgreSQL 9.6) 上测试过,这里是 link:
http://sqlfiddle.com/#!17/f1aac/5
我得到返回正确结果的查询:
select
"items".*,
min(total_usage.total_count) as total_usage,
count(user_usage.id) as user_usage
from "items"
left join
(select item_id,count(item_id) as total_count from item_usages group by item_id) as total_usage
on "items"."id" = "total_usage"."item_id"
left join "item_usages" as "user_usage"
on "user_usage"."item_id" = "items"."id" and "user_usage"."user_id" = 99
group by "items"."id";
但我不知道性能如何,所以如果可能的话我仍然会找到更快的查询并且仍然想知道:
为什么我的第一个查询给出了错误的结果?
您查询 returns 高数字的原因是您加入了 2 次。
(来自 Nganu 的一侧)第一个连接将产生 4 行,第二个连接将这 4 行与 3 行相同的 table 映射,产生 12 行。
您只需 1 个连接即可解决此问题:
select "items".id,
count(total_usage.id) as total_usage,
sum(case when total_usage.user_id = 99 then 1 else 0 end) as user_usage
from "items"
left join "item_usages" as "total_usage" on "items"."id" = "total_usage"."item_id"
group by "items".id
而且它应该工作得更快(尽管在小数据集上不可见)