我如何编写SQL查询来包含所有类别的每月计数,即使不存在任何记录,也会显示所有月份和类别
我正在使用SSR,我正在尝试填充一个报告,以显示按类别分组的每月计数。报告中的类别应列为行标题,一年中的所有月份应列为列标题。要求是,我需要显示所有月份和类别,无论这些列/行中是否有数据 我的问题是构造SQL查询来实现这一点 以下是我正在使用的表格示例: 交易表:我如何编写SQL查询来包含所有类别的每月计数,即使不存在任何记录,也会显示所有月份和类别,sql,reporting-services,grouping,sql-server-2012,Sql,Reporting Services,Grouping,Sql Server 2012,我正在使用SSR,我正在尝试填充一个报告,以显示按类别分组的每月计数。报告中的类别应列为行标题,一年中的所有月份应列为列标题。要求是,我需要显示所有月份和类别,无论这些列/行中是否有数据 我的问题是构造SQL查询来实现这一点 以下是我正在使用的表格示例: 交易表: create table [Transaction] ( ContactID int Primary Key , CategoryID int , DateKey int ) 日历表: 请注意,这个表最
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...
我知道它涉及一些外部联接、分组方式和子查询的组合。我就是不知道如何才能做到这一点
如果有人能在这个问题上帮助我,我将非常高兴
create table [Calendar] (
DateID int Primary Key
, Date datetime
, Year nchar(4)
, Month nvarchar(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
您可以使用
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
谢谢你的回复!你是我的英雄!虽然我现在确实明白了为什么SSAS和MDX使这些查询变得更容易,但学习曲线相当陡峭,但我还是能够实现这一点。请注意,我无法使用“提取”功能。我用月(日)代替。我相信extract是MySql代码?不管怎样,它是有效的,非常感谢。到时候,我也会成为SQL专家。