3

我正在使用 SSRS,并且正在尝试填充报告以显示按类别分组的每月计数。该报告应将类别列为行标题,并将一年中的所有月份显示为列标题。要求是我需要显示所有月份和类别,无论这些列/行中是否有数据。

我的问题是构建 SQL 查询来做到这一点。

以下是我正在使用的表的示例:

交易表:

create table [Transaction] (
     ContactID int Primary Key
     , CategoryID int
     , DateKey int
)

日历表:

请注意,该表最初是作为用于 SSAS 的日期维度创建的,但我决定不使用 SSAS,因为多维数据集开发对我来说越来越困难。此表中还有许多其他字段,但这些是有关此问题的重要字段。

create table [Calendar] (
     DateID int Primary Key
     , Date datetime
     , Year nchar(4)
     , Month nvarchar(2)
)

类别表:

create table [Category] (
     CategoryID int Primary Key
     , CategoryName nvarchar
)

查询需要返回要在 SSRS 中使用的数据集,以填充类似于以下内容的报告:

Category   |   Jan  |  Feb  | Mar  |  Apr  |  May  |  June  | etc...
--------------------------------------------------------------------
Category A |   -    |   -   |  -   |   -   |   -   |   -    | etc...
--------------------------------------------------------------------
Category B |   -    |   -   |  -   |   -   |   -   |   -    | etc...
--------------------------------------------------------------------
Category C |   -    |   -   |  -   |   -   |   -   |   -    | etc...

我知道它涉及到 OUTER JOINS、GROUP BY 和子查询的某种组合。我只是想不通如何做到这一点。

如果有人可以在这个问题上帮助我,我会很高兴。

谢谢

4

2 回答 2

2

以下查询获取事务中的所有类别。它通过从日期中提取月份并计算交易数量来以月份为中心。这将为数据中的所有类别返回一行

select c.categoryName,
       sum(case when extract(month from date) = 1 then 1 else 0 end) as Jan,
       sum(case when extract(month from date) = 2 then 1 else 0 end) as Feb,
       sum(case when extract(month from date) = 3 then 1 else 0 end) as Mar,
       . . . 
from transaction t join
     category c
     on t.categoryID = c.categoryID 
group by categoryName
order by categoryName

如果您确实需要所有类别,即使根本没有交易,也可以使用右外连接:

select c.categoryName,
       sum(case when extract(month from date) = 1 then 1 else 0 end) as Jan,
       sum(case when extract(month from date) = 2 then 1 else 0 end) as Feb,
       sum(case when extract(month from date) = 3 then 1 else 0 end) as Mar,
       . . . 
from transaction t right outer join
     category c
     on t.categoryID = c.categoryID 
group by categoryName
order by categoryName
于 2012-09-21T18:26:34.773 回答
0

您可以使用以下PIVOT功能:

WITH Data AS
(   SELECT  CategoryName,
            Calendar.[Month],
            ContactID 
    FROM    Category
            LEFT JOIN [Transaction] 
                ON [Transaction].CategoryID = Category.CategoryID
            LEFT JOIN Calendar
                AND [Transaction].DateKey = Calendar.DateID
)
SELECT  CategoryName, 
        [1] AS [Jan],
        [2] AS [Feb],
        [3] AS [Mar],
        [4] AS [Apr],
        [5] AS [May],
        [6] AS [Jun],
        [7] AS [Jul],
        [8] AS [Aug],
        [9] AS [Sep],
        [10] AS [Oct],
        [11] AS [Nov],
        [12] AS [Dec]
FROM    Data
        PIVOT
        (   COUNT(ContactID)
            FOR [Month] IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
        ) pvt
于 2012-09-21T19:27:56.437 回答