【问题标题】:Most efficient way to return parent rows and child aggregates in one-to-many relationship以一对多关系返回父行和子聚合的最有效方法
【发布时间】:2012-08-31 16:51:44
【问题描述】:

假设我有两个具有一对多关系的表。我想创建一个视图/查询,显示父行中的所有列并汇总子行中的总计。这是我经常遇到的一个场景,我不禁觉得我错过了一个更好、更明显的解决方案。我使用的一种是针对子表的多个连接,例如:

SELECT vt.*, COALESCE(count(mvAyes.*), 0) as Ayes, COALESCE(count(mvNoes.*), 0) as Noes  FROM VoteTable vt 
LEFT JOIN MemberVote mvAyes on mvAyes.VoteId = vt.Id AND mvAyes.Vote = 'Aye'
LEFT JOIN MemberVote mvNoes on mvNoes.VoteId = vt.Id AND mvNoes.Vote = 'No'
GROUP BY vt.Col1, vt.Col2 ... (all columns in Vote table)

另一种解决方案是使用相关子查询,据我了解,它的效率非常低,尽管我认为上面的多重连接解决方​​案也非常低效。

那么,有没有我不知道的更好的解决方案?谢谢!

【问题讨论】:

    标签: sql sql-server-2008


    【解决方案1】:

    是的,有一个更简单的解决方案:

    SELECT vt.*,
           sum(case when mv.Vote = 'Aye' then 1 else 0 end) as Ayes,
           sum(case when mv.Vote = 'No' then 1 else 0 end) as Nos
    FROM VoteTable vt left outer join
         MemberVote mv
         on mv.VoteId = vt.Id 
    GROUP BY vt.Col1, vt.Col2 ... (all columns in Vote table)
    

    您可以通过在子查询中进行分组来进一步简化此操作:

    select vt.*, mv.ayes, mv.noes
    from vt left outer join
         (select VoteId, sum(case when mv.Vote = 'Aye' then 1 else 0 end) as Ayes,
                 sum(case when mv.Vote = 'No' then 1 else 0 end) as Nos
          from MemberVote mv
          group by VoteId
         ) mv
         on vt.id = mv.VoteId
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-16
      • 1970-01-01
      • 2020-09-02
      • 1970-01-01
      • 1970-01-01
      • 2013-02-23
      相关资源
      最近更新 更多