2017-07-03 46 views
1

我有一個查詢如何聯合彙總查詢?

SELECT 
    CntApp = COUNT(app.ApplicationID) 
    ,r.RegionName 
    ,d.DistrictName 
FROM dim.Application app 
    JOIN dim.Geography g ON (app.ApplicationID = g.GeographyID) 
     AND (app.CountryId = g.CountryId) 
    JOIN dim.Region r ON r.RegionID = g.RegionID 
    JOIN dim.District d ON d.DistrictId = g.DistrictID 
    JOIN dim.ZIPcode z ON g.ZIPcodeID = z.ZIPcodeID   
GROUP BY 
    r.RegionName 
    ,d.DistrictName 

SELECT 
    CntCon = COUNT(c.ContractID) 
    ,r.RegionName 
    ,d.DistrictName 
FROM dim.Contract c 
    JOIN dim.Geography g ON (c.ContractID = g.GeographyID) 
     AND (c.CountryId = g.CountryId) 
    JOIN dim.Region r ON r.RegionID = g.RegionID 
    JOIN dim.District d ON d.DistrictId = g.DistrictID 
    JOIN dim.ZIPcode z ON g.ZIPcodeID = z.ZIPcodeID   
GROUP BY 
    r.RegionName 
    ,d.DistrictName 

,我要合併到一個表,所以在GROUP BY仍然有效。 結果我想:

CntApp | CntCon | RegionName | DistrictName 
31  24  Pardubicky Pardubice 
21  16  Pardubicky Chrudim 
... 

我試過UNION ALL卻得到了這樣的事情,而不是:

CntApp | CntCon | RegionName | DistrictName 
    NULL  24  Pardubicky Pardubice 
    21  NULL  Pardubicky Pardubice 
    26  NULL  Pardubicky Chrudim 
    ... 

Appereantly,StackOverflow上認爲我應該包括更多的文字(「它看起來像你的崗位主要是代碼,請添加一些更多的細節「),所以在這裏它是:

,-""-. 
    :======: 
    :======; 
    `-.,-' 
     || 
    _,''--. _____ 
    (/ __ `._| 
    ((_/_)\  | 
    (____)`.___| 
    (___)____.|_____ 
       SSt 
+0

所以,你得到了什麼呢,當你UNION這一切? (好的繪畫+1和幽默感;) –

+1

@Rafal:看編輯。 –

+0

當查詢幾乎完全相同時,您可以通過不進行UNION來優化您的查詢;你有效地要求數據庫加入同一組表並計算兩次。有辦法避免這種情況...(我發佈了一個無聯合答案作爲替代) –

回答

1

UNION ALL將列與結果相結合柱。您需要引入假列,再次聚集它(或其他溶液加入等):

SELECT SUM(CntApp) CntApp, SUM(CntCon) CntCon, RegionName, DistrictName FROM (

    SELECT 
     CntApp = COUNT(app.ApplicationID) 
     ,CntCon = 0 
     ,r.RegionName 
     ,d.DistrictName 
    FROM dim.Application app 
     JOIN dim.Geography g ON (app.ApplicationID = g.GeographyID) 
      AND (app.CountryId = g.CountryId) 
     JOIN dim.Region r ON r.RegionID = g.RegionID 
     JOIN dim.District d ON d.DistrictId = g.DistrictID 
     JOIN dim.ZIPcode z ON g.ZIPcodeID = z.ZIPcodeID   
    GROUP BY 
     r.RegionName 
     ,d.DistrictName 

    UNION ALL 

    SELECT 
     CntApp = 0 
     ,CntCon = COUNT(c.ContractID) 
     ,r.RegionName 
     ,d.DistrictName 
    FROM dim.Contract c 
     JOIN dim.Geography g ON (c.ContractID = g.GeographyID) 
      AND (c.CountryId = g.CountryId) 
     JOIN dim.Region r ON r.RegionID = g.RegionID 
     JOIN dim.District d ON d.DistrictId = g.DistrictID 
     JOIN dim.ZIPcode z ON g.ZIPcodeID = z.ZIPcodeID   
    GROUP BY 
     r.RegionName 
     ,d.DistrictName 
) d 
GROUP BY RegionName, DistrictName 
+0

我有同樣的想法,除了我用NULL而不是CntApp = 0。 不幸的是,它爲CntApp和CntCont返回相同的值,不應該這樣做。 –

+0

如果這沒有回答你的問題,爲什麼你將它標記爲答案? –

+0

@StanislavJirák - 你的意思是我提供的查詢返回相同的值,或者一個是你使用了空值? –

2

您需要join 2子查詢。這樣,您將按照您的期望並排查詢兩個查詢的列。

這應該工作:

SELECT iq1.CntApp , iq2.CntCon, iq1.iq1.RegionName,iq1.DistrictName 
FROM 
(
SELECT 
    CntApp = COUNT(app.ApplicationID) 
    ,r.RegionName 
    ,d.DistrictName 
FROM dim.Application app 
    JOIN dim.Geography g ON (app.ApplicationID = g.GeographyID) 
     AND (app.CountryId = g.CountryId) 
    JOIN dim.Region r ON r.RegionID = g.RegionID 
    JOIN dim.District d ON d.DistrictId = g.DistrictID 
    JOIN dim.ZIPcode z ON g.ZIPcodeID = z.ZIPcodeID   
GROUP BY 
    r.RegionName 
    ,d.DistrictName 
) iq1 
inner join 
(
SELECT 
    CntCon = COUNT(c.ContractID) 
    ,r.RegionName 
    ,d.DistrictName 
FROM dim.Contract c 
    JOIN dim.Geography g ON (c.ContractID = g.GeographyID) 
     AND (c.CountryId = g.CountryId) 
    JOIN dim.Region r ON r.RegionID = g.RegionID 
    JOIN dim.District d ON d.DistrictId = g.DistrictID 
    JOIN dim.ZIPcode z ON g.ZIPcodeID = z.ZIPcodeID   
GROUP BY 
    r.RegionName 
    ,d.DistrictName 
) iq2 
on 
iq1.RegionName = iq2.iq1.RegionName 
and 
iq1.DistrictName = iq2.DistrictName 
+0

INNER JOIN是一個明智的選擇嗎?有一種風險是,一個子查詢將不會有特定區域/區域配對的行,因此行將從輸出中丟失 –

+1

這就是爲什麼我已經突出顯示頂部的「加入」:)直到我們沒有從OP得到適當的數據,我們不能評論左/右或內心。我選擇inner作爲示例,因爲它不會返回任何NULL列。 –

1

你需要一個FULL JOIN

SELECT coalesce(app.RegionName, c.RegionName) AS RegionName, 
     coalesce(app.DistrictName, c.DistrictName) AS DistrictName, 
     coalesce(app.CntApp,0) AS CntApp, 
     coalesce(c.CntCon,0) AS CntCon 
FROM 
    (SELECT 
     CntApp = COUNT(app.ApplicationID) 
     ,r.RegionName 
     ,d.DistrictName 
    FROM dim.Application app 
     JOIN dim.Geography g ON (app.ApplicationID = g.GeographyID) 
     AND (app.CountryId = g.CountryId) 
     JOIN dim.Region r ON r.RegionID = g.RegionID 
     JOIN dim.District d ON d.DistrictId = g.DistrictID 
     JOIN dim.ZIPcode z ON g.ZIPcodeID = z.ZIPcodeID   
    GROUP BY 
     r.RegionName 
     ,d.DistrictName 
    ) app 
    FULL JOIN 
    (
     SELECT 
     CntCon = COUNT(c.ContractID) 
     ,r.RegionName 
     ,d.DistrictName 
    FROM dim.Contract c 
     JOIN dim.Geography g ON (c.ContractID = g.GeographyID) 
     AND (c.CountryId = g.CountryId) 
     JOIN dim.Region r ON r.RegionID = g.RegionID 
     JOIN dim.District d ON d.DistrictId = g.DistrictID 
     JOIN dim.ZIPcode z ON g.ZIPcodeID = z.ZIPcodeID   
    GROUP BY 
     r.RegionName 
     ,d.DistrictName 
    ) c ON app.RegionName = c.RegionName AND app.DistrictName = c.DistrictName 
0

你也許能夠擺脫工會,這將是更安全因爲你的結果不會被流浪笛卡爾的影響加入,如果壞數據打交道的方式進入G/R/d/Z表可能會發生:

SELECT 
CntApp, 
CntCon, 
r.RegionName, 
d.DistrictName 
FROM 
dim.Geography g 
INNER JOIN dim.Region r ON r.RegionID = g.RegionID 
INNER JOIN dim.District d ON d.DistrictId = g.DistrictID 
INNER JOIN dim.ZIPcode z ON g.ZIPcodeID = z.ZIPcodeID 

LEFT JOIN (SELECT ApplicationID, CountryID, COUNT(*) CntApp FROM dim.Application GROUP BY ApplicationID, CountryID) app 
    ON (app.ApplicationID = g.GeographyID) AND (app.CountryId = g.CountryId) 

LEFT JOIN (SELECT ContractID, CountryId, COUNT(*) as CntCon FROM dim.Contract GROUP BY ContractID, CountryId) c  
    ON (c.ContractID = g.GeographyID) AND (c.CountryId = g.CountryId) 

這裏有點教育點爲你雖然:

如果你有兩個數據塊(來自表格,查詢等等),並且你想把它們垂直放在一起(更多的行),那麼你使用UNION 如果你想水平地把它們合併(更多列)使用JOIN

如果我們有:

a,b,c 
a,b,c 
a,b,c 

而且

a,y,z 
a,y,z 
a,y,z 

這是你與UNION得到:

a,b,c 
a,b,c 
a,b,c 
a,y,z 
a,y,z 
a,y,z 

這是你會得到什麼JOIN:

a,b,c,y,z 
a,b,c,y,z 
a,b,c,y,z 

記住這一點,是將竭誠爲您服務以及