将聚合数据分组到单独的表中

Grouping aggregated data in separate tables

关于我之前的问题 ,我正在尝试 COUNT HISTORY table 和 OPPORTUNITIES table 中的记录],然后按 CREATE_DATE 的年份和季度分组。

我希望每个季度的结果网格中有一行,一列用于 HISTORY 条记录,一列用于 OPPORTUNITIES 条记录:

+---------+---------------+---------------+
| Quarter | History Items | Opportunities |
+---------+---------------+---------------+
| 2017 Q1 |            15 |            25 |
| 2017 Q2 |            12 |            16 |
| 2017 Q3 |            13 |            18 |
| 2017 Q4 |            16 |            20 |
| 2018 Q1 |            17 |            18 |
+---------+---------------+---------------+

我可以为 table 获得我想要的结果,但是一旦我尝试加入他们,我就会遇到问题。我尝试了各种 JOINUNION 版本,但似乎无法正确使用。我可以看到我尝试的所有编码中的潜在问题,但无法弄清楚如何编写没有这些问题的代码。这是工作单 table SELECT 查询:

SELECT DATENAME(year, H.CREATE_DATE) + ', Qtr' + DATENAME(quarter, H.CREATE_DATE) AS Period,
       COUNT(H.ID) AS [History Items]
FROM   HISTORY AS H 
GROUP BY DATENAME(year, H.CREATE_DATE), DATENAME(quarter, H.CREATE_DATE)
ORDER BY Period;

还有我尝试添加的版本之一 table:

SELECT DATENAME(year, O.CREATE_DATE) + ', Qtr' + DATENAME(quarter, O.CREATE_DATE) AS Period,
       COUNT(O.ID) AS Opportunities,
       COUNT(H.ID) AS [History Items]
FROM   OPPORTUNITY AS O FULL JOIN
       HISTORY AS H ON DATENAME(year, O.CREATE_DATE) + DATENAME(quarter, O.CREATE_DATE) =
                       DATENAME(year, H.CREATE_DATE) + DATENAME(quarter, H.CREATE_DATE)
GROUP BY DATENAME(year, O.CREATE_DATE), DATENAME(quarter, O.CREATE_DATE)
ORDER BY Period;

为了便于测试和进一步说明,here is a sample database with what I've been working on in sql fiddle

一种简单的方法是使用 UNION ALL 来连接两个结果。这可能更清晰,更容易。您也可以像您尝试的那样使用 FULL OUTER JOIN,但是使用 CTEderivied table

; WITH 
hist as
(
     -- your hist query 
    SELECT DATENAME(year, H.CREATE_DATE) 
           + ', Qtr' + DATENAME(quarter, H.CREATE_DATE) AS Period,
           COUNT(H.ID) AS [History Items]
    FROM   HISTORY AS H 
    GROUP BY DATENAME(year, H.CREATE_DATE), DATENAME(quarter, H.CREATE_DATE)
),
opp as
(
     -- the opportunity query
     SELECT DATENAME(year, O.CREATE_DATE) 
            + ', Qtr' + DATENAME(quarter, O.CREATE_DATE) AS Period,
            COUNT(O.ID) AS [Opportunities]
     FROM   OPPORTUNITY AS O
     GROUP BY DATENAME(year, O.CREATE_DATE), DATENAME(quarter, O.CREATE_DATE)
),
CTE as
(
     -- union both query together
     SELECT Period, [History Items], [Opportunities] = 0
     FROM   hist h
     UNION ALL
     SELECT Period, [History Items] = 0, Opportunities
     FROM   Oppr
)
-- final result
SELECT Period, 
       [History Items] = SUM([History Items]), 
       [Opportunities] = SUM([Opportunities])
FROM   CTE
GROUP BY Period
ORDER BY Period

-- FULL OUTER JOIN version. using the same hist & opp from previous query
SELECT Period = COALESCE(h.Period, o.Period),
       [History Items] = SUM([History Items]), 
       [Opportunities] = SUM([Opportunities])
FROM   hist h
       FULL OUTER JOIN opp o ON h.Period = o.Period
GROUP BY COALESCE(h.Period, o.Period)
ORDER BY Period