如何指望 join a table with 2 conditions?

How to count on join a table with 2 conditions?

我有一个itemstable

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

而且它应该工作得更快(尽管在小数据集上不可见)