繁体   English   中英

如何合并汇总查询?

[英]How to union aggregated queries?

我有一个查询

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

我想将其合并到一个表中,因此该分组依据仍然有效。 我想要得到的结果:

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
    ...

您需要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 

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

您需要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

您可能可以放弃联合,这将更加安全,因为如果坏数据进入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

记住这一点,会很好地为您服务

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM