从两个表中总结结果的最快方法

时间:2018-01-26 09:47:31

标签: sql sql-server tsql

我有两张桌子如下。现在我需要[Occures]的总和,用于共享相同[FirstName]的所有记录。

enter image description here

要做到这一点,我们现在使用一个union,然后按照下面的函数分组:

create table #foo(FirstName varchar(500), Occures int)
create table #bar(FirstName varchar(500), Occures int)
create table #fb(FirstName varchar(500), Occures int)
 insert into #foo values('a', 1)
 insert into #foo values('b', 2)
 insert into #foo values('c', 3)
 insert into #foo values('d', 4)
 insert into #bar values('c', 1)
 insert into #bar values('d', 2)
 insert into #bar values('g', 3)
 insert into #bar values('h', 4);

 insert into #fb
        select * from #foo 
  union select * from #bar
        select FirstName
             , sum(Occures) as Occures 
          from #fb 
      group by FirstName

drop table #foo
drop table #bar
drop table #fb

我需要以下结果:

enter image description here

有一种更可思议的整洁方式吗?我试图让这个更快,因为当前表有很多行和良好的索引,我希望有一个解决方案,我加入当前表而不是通过临时表或cte抽一切。

3 个答案:

答案 0 :(得分:1)

根据您的描述,您似乎想要:

select name, sum(occures)
from ((select name, occures from #foo) union all
      (select name, occures from #bar)
     ) fb
group by name;

如果我假设以下内容:

  • 两个表中都没有重复的名称。
  • 您只需要两个表中的名称。

然后您可以使用join

select f.name, (f.occures + b.occures) as occures
from #foo f join
     #bar b
     on f.name = b.name;

使用正确的索引,这会更快。

答案 1 :(得分:0)

我同意Gordon的上述内容,表中需要有索引来防止不必要的性能问题。

我的答案如下:

DECLARE @FOO TABLE (FirstName VARCHAR(5), Occures INT)
DECLARE @BAR TABLE (FirstName VARCHAR(5), Occures INT)

INSERT INTO @FOO(FirstName,Occures) VALUES
('a',1)
,('b',2)
,('c',3)
,('d',4)

INSERT INTO @BAR(FirstName,Occures) VALUES
('c',1)
,('d',2)
,('g',3)
,('h',4)


DECLARE @SearchName VARCHAR(5) = 'D'

SELECT   COALESCE(B.FirstName, F.FirstName) AS FirstName
        ,SUM(ISNULL(B.Occures, 0) + ISNULL(F.Occures, 0)) AS TotalOccures
FROM @FOO F
    FULL OUTER JOIN @BAR B ON B.FirstName = F.FirstName
WHERE 1=1
    AND (B.FirstName = @SearchName OR F.FirstName = @SearchName)
GROUP BY
        B.FirstName
        ,F.FirstName

我在示例中使用了临时表,但您可以使用real / temp表。但是如果你在真实世界的查询中使用上述内容,我会避免使用#temp表,除非绝对必要,再次为了性能。

答案 2 :(得分:0)

这主要是现有答案的重复

主键应该有帮助

第一个是第二个成本的1/2 没有订单的成本是相同的

declare @foo table (FirstName varchar(500) primary key, Occures int);
declare @bar table (FirstName varchar(500) primary key, Occures int);
 insert into @foo values
    ('a', 1) 
  , ('c', 3)
  , ('b', 2)
  , ('d', 4);
 insert into @bar values
    ('c', 1)
  , ('g', 3)
  , ('h', 4)
  , ('d', 2);


select FirstName, sum(Occures) as SumOccures 
from ( select FirstName, Occures from @foo 
       union all 
       select FirstName, Occures from @bar 
     ) tt
group by FirstName
order by FirstName 

select isnull([@foo].FirstName, [@bar].FirstName)
     , sum(isnull([@foo].Occures, 0) + isnull([@bar].Occures, 0)) as SumOccures
from @foo 
full outer join @bar 
  on [@foo].FirstName = [@bar].FirstName 
group by [@foo].FirstName, [@bar].FirstName  
order by isnull([@foo].FirstName, [@bar].FirstName)