我该怎么做这个SQL查询(聚合group by和where子句)?

时间:2015-01-07 19:38:32

标签: mysql sql

这是问题的过度简化版本,我有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
)

有些组织对某个类别的项目出价。投标人可以赢得或失去对项目的投标,然后计算评级(获胜次数/总数)。评级是在组织与另一组织(或多于一个)之间计算的。

例如:

  1. 我们希望显示项目所有投标人的评级,包括仅暗示与项目所有者相同的组织的项目的投标。
  2. 我们希望显示项目类别中所有投标人的评级,仅包括其他选定组织也暗示的项目的投标。
  3. 据我所知,获取结果不需要评级表,但由于数据量大,执行查询需要花费太多时间。因此,我创建了评级表来保存在同一个项目上工作的投标人的关联。如果两个投标人以前从未合作过,可能没有评级。

    我会尝试用自己的方式更新,但我似乎无法让它工作......当我们没有评级时,我在结果中丢失了投标人,我使用选定的IN子句过滤的组织。

    编辑:我找到了解决问题的方法。我在内部查询中添加了一个列,如果当前行在所选组织中,则返回一个布尔值。当我执行SUM时,那些不是IN的,不计入评级的计算中。

    总之,当我尝试使用HAVING子句时,它会消除没有评级的行,但我仍然希望它们在最终结果中。我想知道他们是0。

1 个答案:

答案 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