这就是我的SQL表结构的样子:
CREATE TABLE TempCategory
(
Id BIGINT,
Name VARCHAR(100)
)
CREATE TABLE TempSubCategory
(
Id BIGINT,
CategoryId BIGINT,
Name VARCHAR(100)
)
CREATE TABLE TempProduct
(
Id BIGINT,
SubCategoryId BIGINT,
Name VARCHAR(100)
)
http://sqlfiddle.com/#!3/2606fd/4
我正在编写一份SSRS报告,将“类别”显示为x轴,“子类别”显示为y轴,“产品”显示为数据。每个类别都有自己的子类别,因此我在每个行组的列组中显示子类别。
SSRS报告不会为没有获取值的行绘制单元格。所以我的报告最终看起来像这样:
这是我当前查询的样子:
SELECT TempCategory.Id, 'MainCategoryId',
TempCategory.Name 'CategoryName',
TempSubCategory.id 'SubCategoryId',
TempSubCategory.Name 'SubCategory',
TempProduct.Id 'ProductId',
TempProduct.Name 'ProductName'
FROM TempCategory
INNER JOIN TempSubCategory
ON TempCategory.Id = TempSubCategory.CategoryId
INNER JOIN TempProduct
ON TempSubCategory.Id = TempProduct.SubCategoryId
我要做的是修改查询,使其始终返回每个子类别组相同的行数,以便我在其拥有数据的行中有空值或0。
例如:类别1有3个子类别,最大产品数量在子类别1中,所以我希望查询返回5(子类别1的最大产品数量) 具有主要类别1的每个子类别的行。
对于类别2,每个子类别将返回2行,因为最大数量的产品属于子类别2.
是否可以在SQL中执行此操作,或者在SSRS报告中是否有其他方法可以执行此操作?
- 更新 -
这是一个包含ProductName行组
的表
这是SubCategory列组的矩阵
这是一个包含产品名称行组
的表
答案 0 :(得分:1)
是的,这是一种(环形)方式:
with numbers as -- create lazy numbers table; feel free to replace with a proper one
(
select distinct number
from master..spt_values
where number between 1 and 100
)
, rowCounts as
(
select Category = tc.Name
, SubCategory = tsc.Name
, SubCategoryId = tsc.Id
, MaxSubCatRows = count(1)
from TempCategory tc
inner join TempSubCategory tsc on tc.Id = tsc.CategoryId
inner join TempProduct p on tsc.Id = p.SubCategoryId
group by tc.Name
, tsc.Name
, tsc.Id
)
, maxRowCountPerGroup as
(
select Category
, MaxSubCatRows = max(MaxSubCatRows)
from rowCounts
group by Category
)
, allCats as
(
select rc.Category
, rc.SubCategory
, rc.SubCategoryId
, n.number
from rowCounts rc
inner join maxRowCountPerGroup mr on rc.Category = mr.Category
cross apply (select number
from numbers
where number between 1 and mr.MaxSubCatRows) n
)
, orderedProducts as
(
select *
, productRowNumber = row_number() over (partition by SubCategoryId
order by Id)
from TempProduct
)
select c.Category
, c.SubCategory
, Product = p.Name
from allCats c
left join orderedProducts p on c.subCategoryId = p.subCategoryId
and c.number = p.productRowNumber
order by c.Category
, c.SubCategory
, case when p.Name is null then 1 else 0 end -- nulls last
, p.Name
所以...这是做什么的:
n
占位符行
category / subcategory combo,其中n
是类别的最大值
从上面现在我们有了所需的行数,包括填写SSRS报告所需的NULL
行。
剩下的就是将其应用于报告数据集;坐下来欣赏已出现的额外行。