【问题标题】:SQL Server 2012 : how to get count group by from multiple table joinsSQL Server 2012:如何从多个表连接中获取计数组
【发布时间】:2016-11-02 01:05:51
【问题描述】:

有一个发票表,其中包含创建发票的人。一个人可以属于多个办公室,每个人只能拥有一个主要办公室,但同一个人可以在每个办公室担任多个角色。

declare @person table (personid int)
declare @office table (officeid int, officename varchar(10))
declare @personoffice table (personid int, officeid int, mainoffice bit, personrole varchar(10))
declare @invoice table (personid int)

insert into @person values (1), (2), (3), (4)
insert into @office values (1, 'office1'), (2, 'office2'), (3, 'office3'), (4, 'office4')
insert into @personoffice values (1, 1, 1, 'role1'), (1, 1, 1, 'role2'), (1, 2, 0, 'role1'), (1, 3, 0, 'rolex'), (2, 2, 1, 'role1'), (2, 2, 1, 'role2'), (2, 3, 0, 'rolex'), (3, 3, 1, 'role1'), (3, 4, 0, 'role2')
insert into @invoice values (1), (1), (1), (2), (2), (3), (3), (3), (3), (3)

因此,对于此示例,我们有 3 个人,他们属于多个办公室,但每个人只有一个主要办公室,但有些人每个办公室有多个角色。他们各自创建了多张发票。

我可以通过以下方式获取每人的发票数量:

select 
    i.personid, 
    count(*) InvoiceCountByPerson
from 
    @invoice i
inner join 
    @person p on p.personid = i.personid
group by 
    i.personid

返回:

personid    InvoiceCountByPerson
-------------------------------- 
    1               3
    2               2
    3               5

我需要按总公司名称获取发票数量。主要办公室为 office1 的 Person1 创建了 3 个发票,主要办公室为 office2 的 Person2 创建了 2 个发票,而主要办公室为 office3 的 Person3 创建了 5 个发票,因此预期结果:

officename  InvoiceCountByOfficeName 
------------------------------------
office1              3
office2              2
office3              5

这不起作用:

select 
    o.officename,
    count(*) InvoiceCountByOfficeName
from 
    @invoice i
inner join 
    @person p on p.personid = i.personid
inner join 
    @personoffice po on po.personid = p.personid AND po.mainoffice = 1
inner join 
    @office o on o.officeid = po.officeid
group by 
    o.officename

返回时:

officename  InvoiceCountByOfficeName 
-------------------------------------
office1                 6
office2                 4
office3                 5

由于同一个人有多个具有不同角色的 mainoffice = 1 记录,因此我需要在 @personoffice 连接上进行某种区分。数百万张发票也需要考虑性能。

【问题讨论】:

  • 每次阅读格式良好的 sql 问题时,我都非常高兴 :-)。 +1 仅用于包含所有相关细节。
  • inner join (select distinct ... from @personoffice)?
  • 那么您需要发票属于第一个主要办公室吗?
  • @DhruvJoshi 每人只有一个主要办公室。

标签: sql sql-server count sql-server-2012 group-by


【解决方案1】:

你是如此接近......你所要做的就是使用派生表而不是直接使用@personoffice 表:

select 
    o.officename,
    count(*) InvoiceCountByOfficeName
from 
    @invoice i
inner join 
    @person p on p.personid = i.personid
inner join 
    (
        select distinct personid, officeid
        from @personoffice
        where mainoffice = 1
    )
     po on po.personid = p.personid 
inner join 
    @office o on o.officeid = po.officeid
group by 
    o.officename

结果:

officename InvoiceCountByOfficeName
---------- ------------------------
office1    3
office2    2
office3    5

【讨论】:

  • 这是只运行一次派生表还是每人运行一次?
  • 派生表只运行一次,与为主选择子句中的每一行运行的子查询(选择子句内的选择)相反。
【解决方案2】:
    select 
        o.officename,
        count(*) InvoiceCountByOfficeName
    from 
        @invoice i
    inner join 
        @person p on p.personid = i.personid
    inner join 
        (
        select distinct personid,officeid,mainoffice from @personoffice
        ) po on po.personid = p.personid AND po.mainoffice = 1
    inner join 
        @office o on o.officeid = po.officeid
    group by 
        o.officename

谢谢

【讨论】:

  • 最好把mainoffice = 1condition作为where子句放在派生表中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-27
  • 2019-10-04
  • 1970-01-01
  • 2017-05-17
  • 1970-01-01
  • 2012-01-21
相关资源
最近更新 更多