子查询的差异

时间:2018-08-05 07:33:33

标签: mysql sql

Problem statement link

正确的代码(by dongyuzhang):

select con.contest_id,
        con.hacker_id, 
        con.name, 
        sum(total_submissions), 
        sum(total_accepted_submissions), 
        sum(total_views), sum(total_unique_views)
from contests con 
join colleges col on con.contest_id = col.contest_id 
join challenges cha on  col.college_id = cha.college_id 
left join
(select challenge_id, sum(total_views) as total_views, sum(total_unique_views) as total_unique_views
from view_stats group by challenge_id) vs on cha.challenge_id = vs.challenge_id 
left join
(select challenge_id, sum(total_submissions) as total_submissions, sum(total_accepted_submissions) as total_accepted_submissions from submission_stats group by challenge_id) ss on cha.challenge_id = ss.challenge_id
    group by con.contest_id, con.hacker_id, con.name
        having sum(total_submissions)!=0 or 
                sum(total_accepted_submissions)!=0 or
                sum(total_views)!=0 or
                sum(total_unique_views)!=0
            order by contest_id;

我更改的代码没有子查询,这是不正确的,并且给出了更大的总和值。我不明白编写子查询有何不同?一个简单的示例测试用例将非常有帮助。谢谢!

select con.contest_id,
        con.hacker_id, 
        con.name, 
        sum(total_submissions), 
        sum(total_accepted_submissions), 
        sum(total_views), sum(total_unique_views)
    from contests con 
    join colleges col on con.contest_id = col.contest_id 
    join challenges cha on  col.college_id = cha.college_id 

        left join view_stats vs 
        on cha.challenge_id = vs.challenge_id 
        left join submission_stats ss
        on cha.challenge_id = ss.challenge_id

    group by con.contest_id, con.hacker_id, con.name
    having sum(total_submissions)!=0 or 
    sum(total_accepted_submissions)!=0 or
    sum(total_views)!=0 or
    sum(total_unique_views)!=0
    order by contest_id;

1 个答案:

答案 0 :(得分:1)

通常,对于子查询,首先要在联接之前进行聚合,因此值是正确的,因为每个chalange_id仅具有一行,并且各自的race_id和hacker id都具有正确的总和。 如果先将它们连接在一起,则对主查询中的每个匹配行将这些值汇总一次。

表1:

id | value1
 a | 1   
 a | 2
 b | 3

表2:

id | value2
 a | 5
 a | 6

如果没有子查询就加入(在分组之前)

a | 1 | 5
a | 1 | 6
a | 2 | 5
a | 2 | 6

因此,总和肯定是错误的。

select Table1.id , sum(value1), sum(value2) from
     Table1 join Table2 on Table1.id = Table2.id

会返回

 a | 6 | 22

但是

select Table1.id , sum(value1), max(sum2) from
     Table1 join (select sum(value2) as sum2 from Table2 group by id) t2 on Table1.id = Table2.id

会返回

  a | 3 | 11

我不知道您的查询是否是这种情况,但这是使用子查询的主要区别