如何对三个不相关的表中的值求和

问题描述 投票:0回答:2

我想从两个不相关的表中求和值,但第三个表只有需要连接到其他两个表的状态名,所以我可以有一个完整的状态列表。这是我的代码

    SELECT COALESCE(c.StateName, k.StateName, s.Name) as StateName,
       (COALESCE(c.[Age 17 or Younger],0)+COALESCE( k.[Age 17 or Younger],0)) as [Age 17 or Younger]
FROM NamrsFullDw.UsState 
     Left Join 
      (SELECT StateName, SUM(PerpAge17) AS [Age 17 or Younger] 
      FROM NamrsFrozen2017.CaseKeyIndicator2017
      WHERE FiscalYear = 2017
      GROUP BY StateName
     ) c FULL Outer JOIN
     (SELECT StateName, SUM(PerpAge17) AS [Age 17 or Younger]
      FROM NamrsFrozen2017.KeyIndicator2017
      WHERE FiscalYear = 2017
      GROUP BY StateName
     ) k 
     on c.StateName=k.StateName;
sql sql-server
2个回答
1
投票

您的COALESCE状态名称不是必需的,因为您有一个目录表,其中包含您需要的所有名称,并且您正在通过此字段加入S(顺便说一句,您在选择中使用了别名,但您没有在任何表中使用别名你来自那个名字)。

您还缺少第一次加入时的ON子句

不需要完全连接,因为目录表的左连接涵盖了您所需的内容

COALESCE是SQL ISO标准,但由于您只比较两个值并且您使用的是SQL Server,因此ISNULL更适合执行该操作

使用两个左连接

SELECT 
    s.Name as StateName,
    (ISNULL(c.[Age 17 or Younger],0) + ISNULL( k.[Age 17 or Younger],0)) as [Age 17 or Younger]
FROM NamrsFullDw.UsState S
LEFT JOIN (
    SELECT StateName, SUM(PerpAge17) AS [Age 17 or Younger] 
    FROM NamrsFrozen2017.CaseKeyIndicator2017
    WHERE FiscalYear = 2017
    GROUP BY StateName
) c on c.StateName = S.StateName
LEFT JOIN (
    SELECT StateName, SUM(PerpAge17) AS [Age 17 or Younger]
    FROM NamrsFrozen2017.KeyIndicator2017
    WHERE FiscalYear = 2017
    GROUP BY StateName
) k on k.StateName = s.Name;

或者你可以使用union all

SELECT 
    s.Name as StateName,
    ISNULL(SUM(k.[Age 17 or Younger]),0) as [Age 17 or Younger]
FROM NamrsFullDw.UsState S
LEFT JOIN (
    SELECT StateName, SUM(PerpAge17) AS [Age 17 or Younger] 
    FROM NamrsFrozen2017.CaseKeyIndicator2017
    WHERE FiscalYear = 2017
    GROUP BY StateName
    UNION ALL
    SELECT StateName, SUM(PerpAge17) AS [Age 17 or Younger]
    FROM NamrsFrozen2017.KeyIndicator2017
    WHERE FiscalYear = 2017
    GROUP BY StateName
) k on c.StateName = s.Name
GROUP BY s.Name;

0
投票

像这样......一些样本数据确实有帮助...

drop table #states;
drop table #case_key_indicator;
drop table #key_indicator;

create table #states (StateName char(2));
create table #case_key_indicator (StateName char(2), FiscalYear int, PerpAge17 int);
create table #key_indicator (StateName char(2), FiscalYear int, PerpAge17 int);

insert into #states values ('CA'), ('IA'), ('TX'), ('OR'), ('OH'), ('WI'), ('RI');
insert into #case_key_indicator values ('CA', 2017, 5), ('IA', 2017, 3), ('TX', 2017, 1), ('TX', 2018, 7), ('TX', 2019, 3);
insert into #key_indicator values ('CA', 2017, 5), ('IA', 2019, 3), ('OR', 2017, 1), ('WI', 2018, 1), ('RI', 2017, 1), ('TX', 2017, 2);

with
frozen2017 as
(
select case when c.StateName is null then k.StateName else c.StateName end as StateName
      ,case when c.FiscalYear is null then k.FiscalYear else c.FiscalYear end as FiscalYear
      ,SUM(c.PerpAge17) as sum_c
      ,SUM(k.PerpAge17) as sum_k
      ,isnull(SUM(c.PerpAge17), 0)  + isnull(SUM(k.PerpAge17), 0) AS [Age 17 or Younger]
  from #case_key_indicator c
       full outer join
       #key_indicator k
          on c.StateName = k.StateName
             and c.FiscalYear = k.FiscalYear
 where case when c.FiscalYear is null then k.FiscalYear else c.FiscalYear end = 2017
group by case when c.StateName is null then k.StateName else c.StateName end
        ,case when c.FiscalYear is null then k.FiscalYear else c.FiscalYear end
)
SELECT s.StateName
      ,isnull(z.[Age 17 or Younger], 0) as [Age 17 or Younger]
,*
  FROM #states s
       left outer join
       frozen2017 z
          on s.StateName = z.StateName
order by s.StateName
© www.soinside.com 2019 - 2024. All rights reserved.