Sql 使用左连接、并集和右连接获得所需结果
我有两个表格,即“CProduct”和“DProduct”。以下是示例: C产品:Sql 使用左连接、并集和右连接获得所需结果,sql,ms-access,ms-access-2007,Sql,Ms Access,Ms Access 2007,我有两个表格,即“CProduct”和“DProduct”。以下是示例: C产品: EffectiveDate CFund 2014-01-03 0.06 2014-01-03 0.12 2014-01-06 0.11 D产品: EffectiveDate DFund 2014-01-03 0.06 2014-01-06 0.12 2014-01-08 0.09 我希望得到如下结果: EffectiveDate CFund
EffectiveDate CFund
2014-01-03 0.06
2014-01-03 0.12
2014-01-06 0.11
D产品:
EffectiveDate DFund
2014-01-03 0.06
2014-01-06 0.12
2014-01-08 0.09
我希望得到如下结果:
EffectiveDate CFund DFund
2014-01-03 0.18 0.06
2014-01-06 0.11 0.12
2014-01-08 NULL 0.09
我的问题是:
SELECT a.EffectiveDate,a.CFund,a.DFund
FROM (
SELECT t1.EffectiveDate,Sum(t1.CFund) as CFund ,SUM(t2.DFund) as DFund FROM CProduct t1
LEFT JOIN DProduct t2 ON t1.EffectiveDate = t2.EffectiveDate Group By t1.EffectiveDate
UNION
SELECT t1.EffectiveDate,SUM(t2.CFund) as CFund ,Sum(t1.DFund) as DFund FROM DProduct t1
LEFT JOIN CProduct t2 ON t1.EffectiveDate = t2.EffectiveDate Group By t1.EffectiveDate
) a
但是我没有得到想要的结果。应该只是一些子查询和一个完整的外部联接。不确定您为什么认为需要
联合(特别是因为这样可以消除重复行):
应该只是一些子查询和一个完整的外部联接。不确定您为什么认为需要联合(特别是因为这样可以消除重复行):
为了模拟完全的外部联接,您正在使用带有并集的反向外部联接。这是可以的,但不是必需的,因为SQLServer2008(以及2005)具有完整的外部联接
然而,你的问题更为根本。您将合并来自CProduct和DProduct的所有记录,然后生成总和。因此,假设2014年1月1日,CProduct中有两条记录,DProduct中有三条记录。您的加入将为您提供六条记录(2x3)。然后构建总和,从而将D产品值考虑两倍,将C产品条目考虑三倍
话虽如此,您不希望按日期将每个CProduct记录与每个DProduct记录连接起来。你想加入每个日期的总和。即先聚合,然后加入
select
coalesce(c.effectivedate, d.effectivedate) as effectivedate,
coalesce(c.sumfund,0) as cfund,
coalesce(d.sumfund,0) as dfund
from
(select effectivedate, sum(cfund) as sumfund from cproduct group by effectivedate) c
full outer join
(select effectivedate, sum(dfund) as sumfund from dproduct group by effectivedate) d
on c.effectivedate = d.effectivedate;
没有完全外部连接:
select
c.effectivedate,
c.sumfund as cfund,
d.sumfund as dfund
from
(select effectivedate, sum(cfund) as sumfund from cproduct group by effectivedate) c
left outer join
(select effectivedate, sum(dfund) as sumfund from dproduct group by effectivedate) d
on c.effectivedate = d.effectivedate
union
select
d.effectivedate,
c.sumfund as cfund,
d.sumfund as dfund
from
(select effectivedate, sum(cfund) as sumfund from cproduct group by effectivedate) c
right outer join
(select effectivedate, sum(dfund) as sumfund from dproduct group by effectivedate) d
on c.effectivedate = d.effectivedate;
为了模拟完全的外部联接,您正在使用带有并集的反向外部联接。这是可以的,但不是必需的,因为SQLServer2008(以及2005)具有完整的外部联接
然而,你的问题更为根本。您将合并来自CProduct和DProduct的所有记录,然后生成总和。因此,假设2014年1月1日,CProduct中有两条记录,DProduct中有三条记录。您的加入将为您提供六条记录(2x3)。然后构建总和,从而将D产品值考虑两倍,将C产品条目考虑三倍
话虽如此,您不希望按日期将每个CProduct记录与每个DProduct记录连接起来。你想加入每个日期的总和。即先聚合,然后加入
select
coalesce(c.effectivedate, d.effectivedate) as effectivedate,
coalesce(c.sumfund,0) as cfund,
coalesce(d.sumfund,0) as dfund
from
(select effectivedate, sum(cfund) as sumfund from cproduct group by effectivedate) c
full outer join
(select effectivedate, sum(dfund) as sumfund from dproduct group by effectivedate) d
on c.effectivedate = d.effectivedate;
没有完全外部连接:
select
c.effectivedate,
c.sumfund as cfund,
d.sumfund as dfund
from
(select effectivedate, sum(cfund) as sumfund from cproduct group by effectivedate) c
left outer join
(select effectivedate, sum(dfund) as sumfund from dproduct group by effectivedate) d
on c.effectivedate = d.effectivedate
union
select
d.effectivedate,
c.sumfund as cfund,
d.sumfund as dfund
from
(select effectivedate, sum(cfund) as sumfund from cproduct group by effectivedate) c
right outer join
(select effectivedate, sum(dfund) as sumfund from dproduct group by effectivedate) d
on c.effectivedate = d.effectivedate;
使用聚结或类似方法是正确的解决方案
然而,在您的情况下,可以避免这种情况,其想法是在一个单独的子查询中获取日期,然后通过左键连接到该子查询来获取总和
SELECT
Date.EffectiveDate as EffectiveDate,
t1.Total as t1,
t2.Total as t2
FROM
(select distinct EffectiveDate from CProduct
union
select distinct EffectiveDate from DProduct
) as Date
left join
(select EffectiveDate,SUM(CFund)
from CProduct
group by EffectiveDate) as t1(EffectiveDate,Total)
on Date.EffectiveDate=t1.EffectiveDate
left join
(select EffectiveDate,SUM(DFund)
from DProduct
group by EffectiveDate) as t2(EffectiveDate,Total)
on
Date.EffectiveDate = t2.EffectiveDate
使用聚结或类似方法是正确的解决方案
然而,在您的情况下,可以避免这种情况,其想法是在一个单独的子查询中获取日期,然后通过左键连接到该子查询来获取总和
SELECT
Date.EffectiveDate as EffectiveDate,
t1.Total as t1,
t2.Total as t2
FROM
(select distinct EffectiveDate from CProduct
union
select distinct EffectiveDate from DProduct
) as Date
left join
(select EffectiveDate,SUM(CFund)
from CProduct
group by EffectiveDate) as t1(EffectiveDate,Total)
on Date.EffectiveDate=t1.EffectiveDate
left join
(select EffectiveDate,SUM(DFund)
from DProduct
group by EffectiveDate) as t2(EffectiveDate,Total)
on
Date.EffectiveDate = t2.EffectiveDate
选择E121.EffectiveDate,suM(E12.Cfund)作为Cfund,AVG(E121.Dfund)作为Dfund从E121左侧加入E121上的E12.EffectiveDate=E12.EffectiveDate按E121.EffectiveDate分组选择E121.EffectiveDate,suM(E12.Cfund)作为Cfund,AVG(E121.Dfund)从E121左到E121上的E12。EffectiveDate=E12。EffectiveDate按E121分组。EffectiveDate这会得到您想要的结果-不太清楚为什么其他回答者认为连接和合并如此重要:
SELECT a.EffectiveDate, SUM(a.CFund) AS CFund, SUM(a.DFund) AS DFund
FROM (
SELECT c.EffectiveDate, c.CFund, NULL AS DFund
FROM CProduct c
UNION ALL
SELECT d.EffectiveDate, NULL AS CFund, d.DFund
FROM DProduct d
) a
GROUP BY a.EffectiveDate
ORDER BY a.EffectiveDate
在SQL Fiddle中,针对SQLite(我没有检查,但也应该可以使用Access):这会得到您想要的结果-不太清楚为什么其他回答者认为连接和联合是如此重要:
SELECT a.EffectiveDate, SUM(a.CFund) AS CFund, SUM(a.DFund) AS DFund
FROM (
SELECT c.EffectiveDate, c.CFund, NULL AS DFund
FROM CProduct c
UNION ALL
SELECT d.EffectiveDate, NULL AS CFund, d.DFund
FROM DProduct d
) a
GROUP BY a.EffectiveDate
ORDER BY a.EffectiveDate
在SQL Fiddle中,针对SQLite(我没有检查,但也可以使用Access):有没有不使用合并函数的方法???@vivek为什么要避免合并?@Taemyr,因为我需要与vba(MS-Access)一起使用它这是一个sql函数,在vba中不起作用。@vivek-一个问题最多允许有5个标记,而您只使用了3个,但您认为应用2个SQL Server标记比包含更重要?@vivek有没有不使用合并功能的方法???@vivek为什么要避免合并?@Taemyr,因为我需要将其与vba(MS-ACCESS)一起使用这是一个sql函数,在vba中不起作用。@vivek-一个问题最多允许有5个标记,而您只使用了3个,但您认为应用2个sql Server标记比包含两个问题更重要?@vivek两个问题:1。D产品中是否有重复的日期?2.CProduct中是否有日期在DProduct中不存在?@ZThrosten是的,两个条件都可能存在。两个问题:1。D产品中是否有重复的日期?2.CProduct中是否有日期在DProduct中不存在?@ZThrosten是的,这两个条件都可能存在。当不存在日期条目时,OP请求NULL,因此最后两个合并函数是unecesarry。@Thorsten即使在将coalesce替换为Nz之后,您能否提供与上述查询相同的工作vba查询,它在vba的From子句中给出语法错误。不知道为什么。但是在sql中工作得很好。@vivek:VBA?微软接入?您已将您的请求标记为SQL Server 2008。我认为MS Access不支持完全外部联接,因此我添加了一个模拟查询(尽管我认为您应该能够使用所提供的信息自己构建此查询)。@Thorsten是的,这是我的错误。我为此道歉。我已经改正了。我现在正在尝试。@ThorstenKettner我不太确定“左外连接”是否适用于vba。当日期不存在任何条目时,OP请求NULL,因此最后两个合并函数是unecesarry。@Thorsten您能否提供与上述查询相同的工作vba查询,即使将coalesce替换为Nz,它在vba的From子句中给出语法错误。不知道为什么。但是在sql中工作得很好。@vivek:VBA?微软接入?您已将您的请求标记为SQL Server 2008。我认为MS Access不支持完全外部联接,因此我添加了一个模拟查询(尽管我认为您应该能够使用所提供的信息自己构建此查询)。@Thorsten是的,这是我的错误。我为此道歉。我已经改正了。我现在正在尝试。@ThorstenKettner我不太确定“左外连接”是否适用于vba。能否请您提供等效的工作vba qu