将汇总数据分组到单独的表中

时间:2018-07-16 02:53:06

标签: sql-server aggregate-functions outer-join

关于我先前的问题here,我试图在COUNT表和HISTORY表中OPPORTUNITIES条记录,并按年份和季度对它们进行分组他们的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 |
+---------+---------------+---------------+

我可以得到任何一张表的结果,但是一旦我尝试加入它们,我就会遇到问题。我尝试了各种JOINUNION版本,但似乎无法正确完成。我可以尝试所有尝试,在编码中看到潜在的问题,但无法解决如何编写没有问题的代码。这是工作单表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;

我尝试添加第二个表的版本之一:

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为便于测试和更加清晰。

1 个答案:

答案 0 :(得分:1)

一种简单的方法是使用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