【问题标题】:Grouping aggregated data in separate tables在单独的表中对聚合数据进行分组
【发布时间】:2018-07-16 02:53:05
【问题描述】:

与我之前的问题here 相关,我正在尝试将COUNT 记录在HISTORY 表和OPPORTUNITIES 表中,并按CREATE_DATEs 的年份和季度对它们进行分组。

我希望每个季度的结果网格中有一行,一列用于 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

【问题讨论】:

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


    【解决方案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
    

    【讨论】:

    • 我之前没见过; WITH...那是什么?
    • 那是Common Table Expressiondocs.microsoft.com/en-us/sql/t-sql/queries/…
    • 感谢您的链接。我正在按原样尝试,但也尝试确定是否有办法在没有 CTE 的情况下进行,因为我怀疑基于 SQL Server 但似乎 VERY 有限的解析器可能不与他们合作...
    • 您也可以使用DERIVED TABLE 代替CTE。如果这也不起作用,您还可以考虑创建 2 个视图,一个用于历史记录,另一个用于机会
    • 这对我不起作用,但不是因为它不正确 - 我正在尝试使用的软件受到令人沮丧的限制,但在我能找到它们的任何地方都没有指定这些限制。 ..不确定我将如何实现这个概念,还在寻找。不过感谢您的帮助!
    猜你喜欢
    • 2022-01-23
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    相关资源
    最近更新 更多