2015-01-21 76 views
0

我有兩個表,即 「CProduct」 和 「DPRODUCT」。下面是例子:使用LEFT JOIN,聯盟和右加入以獲得期望的結果

CProduct:

EffectiveDate CFund 
2014-01-03  0.06 
2014-01-03  0.12 
2014-01-06  0.11 

DPRODUCT:

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 

但我沒有得到預期的結果。

+0

有兩個問題:1. DProduct中是否有重複的日期? 2. DProduct中是否存在CProduct中不存在的日期? – 2015-01-21 08:34:36

+0

@ZThrosten是這兩種情況都可能存在。 – vivek 2015-01-21 08:54:42

回答

1

這得到您想要的結果 - 不明白爲什麼其他的應答者認爲連接和COALESCE如此重要的原因:

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小提琴,對SQLite的(我沒有檢查,但應罰款與Access太) :http://sqlfiddle.com/#!7/80158/1

3

應該只是一些子查詢和一個完整的外連接。不知道爲什麼你認爲UNION是必需的(尤其是因爲消除重複行):

SELECT 
    COALESCE(t1.EffectiveDate,t2.EffectiveDate) as EffectiveDate, 
    t1.Total, 
    t2.Total 
FROM 
    (select EffectiveDate,SUM(CFund) 
    from CProduct 
    group by EffectiveDate) as t1(EffectiveDate,Total) 
     full outer join 
    (select EffectiveDate,SUM(DFund) 
    from DProduct 
    group by EffectiveDate) as t2(EffectiveDate,Total) 
     on 
      t1.EffectiveDate = t2.EffectiveDate 
+0

有沒有沒有使用COALESCE函數? – vivek 2015-01-21 07:51:26

+0

@vivek爲什麼你想避免合併? – Taemyr 2015-01-21 08:14:36

+0

@Taemyr,因爲我需要與vba(MS-ACCESS)一起使用它,這是SQL函數,它不會在vba中工作。 – vivek 2015-01-21 08:17:36

1

您使用的是相對的外與UNION爲了模仿FULL OUTER JOIN聯接。這是可以的,但並不是必需的,因爲SQL Server 2008(和2005年也是如此)具有完整的外連接。

但是,您的問題更根本。您將加入來自CProduct和DProduct的所有記錄,然後構建總和。因此,對於日期2014-01-01來說,CProduct中有兩條記錄,DProduct中有三條記錄。你的加入給你六條記錄(2×3)。然後你建立你的總和,因此考慮DProduct值兩倍和CProduct條目三倍。

說了這些之後,您不希望按每個單個DProduct記錄按日期加入每個單個CProduct記錄。你想加入每個日期的總和。即先彙總,然後加入。

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; 

沒有FULL OUTER JOIN:

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; 
+0

當沒有日期條目存在時,OP請求NULL,所以最後兩個聚合函數是不確定的。 – Taemyr 2015-01-21 09:32:33

+0

@Thorsten即使在用Nz替換COALESCE之後,也可以請您提供與上述查詢相當的工作vba查詢,它會在vba中給出From子句中的語法錯誤。 dnt知道爲什麼。但在sql中工作正常。 – vivek 2015-01-21 09:34:53

+0

@Taemyr:你說得對。謝謝。 – 2015-01-21 09:41:05

0

使用合併或類似的是正確的解決方案。

但是在你的情況下可以避免它,想法是在一個單獨的子查詢中獲取日期,然後通過左加入來獲得總和。

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 
+0

即使在用Nz替換COALESCE之後,您是否可以提供與上述查詢相當的工作vba查詢,它在vba中給出From子句中的語法錯誤。 dnt知道爲什麼。但在sql中工作正常。 – vivek 2015-01-21 09:38:14

+0

@vivek此查詢不使用COALESCE。不過,請在Damien的回答中看到我的評論。 – Taemyr 2015-01-21 09:41:07

0

SELECT E121.EffectiveDate,SUM(E12.Cfund)AS CFUND,AVG(e121.Dfund)AS DFUND FROM E121 LEFT JOIN E12 ON E121.EffectiveDate = E12.EffectiveDate GROUP BY E121.EffectiveDate

+0

請格式化爲代碼並稍加解釋。 – Numbers 2015-01-21 10:16:35