我想从两个不相关的表中求和值,但第三个表只有需要连接到其他两个表的状态名,所以我可以有一个完整的状态列表。这是我的代码
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;
您的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;
像这样......一些样本数据确实有帮助...
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