2017-07-03 45 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 

记住这一点,是将竭诚为您服务以及