这是问题的过度简化版本,我有5个表:项目(~50K),组织(~20K),类别,投标人(~250K),评级
Project (
id,
owner_id (Organization.id),
title
)
Organization (
id,
name
)
Category (
id,
name
)
Bidder (
id,
organization_id (Organization.id),
project_id (Project.id)
category_id (Category.id),
is_winner
)
Rating (
id,
bidder_a_id (Bidder.id),
bidder_b_id (Bidder.id),
bidder_a_is_winner,
bidder_b_is_winner
)
有些组织对某个类别的项目出价。投标人可以赢得或失去对项目的投标,然后计算评级(获胜次数/总数)。评级是在组织与另一组织(或多于一个)之间计算的。
例如:
据我所知,获取结果不需要评级表,但由于数据量大,执行查询需要花费太多时间。因此,我创建了评级表来保存在同一个项目上工作的投标人的关联。如果两个投标人以前从未合作过,可能没有评级。
我会尝试用自己的方式更新,但我似乎无法让它工作......当我们没有评级时,我在结果中丢失了投标人,我使用选定的IN子句过滤的组织。
编辑:我找到了解决问题的方法。我在内部查询中添加了一个列,如果当前行在所选组织中,则返回一个布尔值。当我执行SUM时,那些不是IN的,不计入评级的计算中。
总之,当我尝试使用HAVING子句时,它会消除没有评级的行,但我仍然希望它们在最终结果中。我想知道他们是0。
答案 0 :(得分:0)
它看起来像这样(注意在SELECT中使用IN子句):
select
org.id,
sum(sub.nb_wins),
sum(sub.nb_total),
sum(sub.nb_wins) / sum(sub.nb_total)
from
(select
bid.id as bidder_id,
bid.category_id as category_id,
sum(
case rat.id is not null or rat.bidder_a_id in (...) then bid.is_winner else 0
) as nb_wins,
sum(
case rat.id is not null or rat.bidder_a_id in (...) then 1 else 0
) as nb_total
from
Bidder bid
left outer join
Rating rat on rat.bidder_b_id = bid.id
group by
bid.id,
bid.category_id) as sub
inner join
Organization org on org.id = sub.bidder_id
group by
sub.bidder_id,
sub.category_id