Amm*_*arR 18 sql-server-2008 sql-server ssas pivot
每次我决定构建一个立方体时,我都会遇到一个问题,但我还没有找到克服它的方法。
问题是如何允许用户自动定义一系列事物,而无需在维度中对它们进行硬编码。我将在一个例子中解释我的问题。
我有一个叫做客户的表:

这是表中的数据:

我想以枢轴样式显示数据,并将工资和年龄分组在定义的范围内,如下所示:

我写了这个脚本并定义了范围:
SELECT [CustId]
,[CustName]
,[Age]
,[Salary]
,[SalaryRange] = case
when cast(salary as float) <= 500 then
'0 - 500'
when cast(salary as float) between 501 and 1000 then
'501 - 1000'
when cast(salary as float) between 1001 and 2000 then
'1001 - 2000'
when cast(salary as float) > 2000 then
'2001+'
end,
[AgeRange] = case
when cast(age as float) < 15 then
'below 15'
when cast(age as float) between 15 and 19 then
'15 - 19'
when cast(age as float) between 20 and 29 then
'20 - 29'
when cast(age as float) between 30 and 39 then
'30 - 39'
when cast(age as float) >= 40 then
'40+'
end
FROM [Customers]
GO
Run Code Online (Sandbox Code Playgroud)
我的范围是硬编码和定义的。当我将数据复制到 Excel 并在数据透视表中查看时,它显示如下:

我的问题是我想通过将Customers表转换为事实表并创建 2 个维度表SalaryDim和AgeDim来创建多维数据集。
该SalaryDim表有两列(SalaryKey,SalaryRange)和AgeDim表类似于(ageKey,AgeRange)。我的客户事实表有:
Customer
[CustId]
[CustName]
[AgeKey] --> foreign Key to AgeDim
[Salarykey] --> foreign Key to SalaryDim
Run Code Online (Sandbox Code Playgroud)
我仍然需要在这些维度内定义我的范围。每次我将 Excel 数据透视表连接到我的多维数据集时,我只能看到这些硬编码的定义范围。
我的问题是如何直接从数据透视表动态定义范围,而不创建像AgeDim和SalaryDim这样的范围维度。我不想只停留在维度中定义的范围内。

定义的范围是 '0-25' 、 '26-30' 、 '31- 50'。我可能想将其更改为 '0-20'、'21-31'、'32-42' 等,并且用户每次都请求不同的范围。
每次我改变它,我都必须改变维度。我怎样才能改进这个过程?
在多维数据集中实施解决方案会很棒,这样连接到多维数据集的任何 BI 客户端工具都可以定义范围,但我不介意是否有仅使用 Excel 的好方法。
RBa*_*ung 12
根据要求,这是我之前的答案的替代方案,该答案展示了如何使用 Excel 为每个用户执行此操作。这个答案显示了如何使用 T-SQL 来共享/集中执行相同的操作。我不知道如何为此做 Cubes、MDX 或 SSAS 的东西,所以也许 Benoit 或知道的人可以发布它的等价物...
使用以下命令创建一个名为“SalaryRangeData”的新表:
Create Table SalaryRangeData(MinVal INT Primary Key)
Run Code Online (Sandbox Code Playgroud)
通过使用以下命令将计算列包装在视图中来添加计算列:
CREATE VIEW SalaryRanges As
WITH
cteSequence As
(
Select MinVal,
ROW_NUMBER() OVER(Order By MinVal ASC) As Sequence
From SalaryRangeData
)
SELECT
D.Sequence,
D.MinVal,
COALESCE(N.MinVal - 1, 2147483645) As MaxVal,
CAST(D.MinVal As Varchar(32))
+ COALESCE(' - ' + CAST(N.MinVal - 1 As Varchar(32)), '+')
As RangeVals
FROM cteSequence As D
LEFT JOIN cteSequence As N ON N.Sequence = D.Sequence + 1
Run Code Online (Sandbox Code Playgroud)
右键单击 SSMS 中的表并选择“编辑前 200 行”。然后在 MinVal 单元格中输入以下值:0、501、1001 和 2001(顺序对于 SQL Server 无关紧要,它会为我们创建)。关闭表行编辑器并执行 aSELECT * FROM SalaryRanges以查看所有行和范围信息。
执行与上面#1 完全相同的步骤,除了将所有出现的“Salary”替换为“Age”。这应该使表“AgeRangeData”和视图“AgeRanges”。
在 AgeRangeData [MinVal] 列中输入以下值:0、15、20、30 和 40。
将您的 SELECT 语句替换为 CASE 表达式,以使用以下语句检索数据和范围:
SELECT [CustId]
,[CustName]
,[Age]
,[Salary]
,[SalaryRange] = (
Select RangeVals From SalaryRanges
Where [Salary] Between MinVal And MaxVal)
,[AgeRange] = (
Select RangeVals From AgeRanges
Where [Age] Between MinVal And MaxVal)
FROM [Customers]
Run Code Online (Sandbox Code Playgroud)
从现在开始,一切都和现在一样。这些范围应该像当前一样全部显示在您的数据透视表中。
再次转到 SSMS 中的 SalaryRangeData 表行编辑器并删除现有行,然后插入以下值:0, 101, 201, 301, ... 2001(同样,T-SQL 解决方案的顺序无关紧要) . 返回数据透视表并刷新数据。就像 Excel 解决方案一样,数据透视表范围应该自动更改。
添加
CREATE VIEW CustomerView As
SELECT [CustId]
,[CustName]
,[Age]
,[Salary]
,[SalaryRange] = (
Select RangeVals From SalaryRanges
Where [Salary] Between MinVal And MaxVal)
,[AgeRange] = (
Select RangeVals From AgeRanges
Where [Age] Between MinVal And MaxVal)
FROM [Customers]
Run Code Online (Sandbox Code Playgroud)
CustomerView连接到数据库,并在事实表中添加CustomerView视图Data Source Views

我们只需要 customerId,作为客户计数的度量,并且将具有与维度相同的事实表






如果您需要更改范围,更改数据SalaryRangeData和AgeRangeData,然后就重新处理维度和多维数据集
这是我在 Excel 中的操作方法...
插入一个新工作表,将其命名为“Salary Ranges”。在第一行中,按顺序添加文本标题“Min”、“Max”和“Range”(分别应为单元格 A1、A2、A3)。
在单元格 B2 中添加以下公式:
=IF(A2="","",IF(A3="","+",A3-1))
Run Code Online (Sandbox Code Playgroud)
在单元格 C2 中添加以下公式:
=IF(B2="","",A2 & IF(B2="+",""," - ") & B2)
Run Code Online (Sandbox Code Playgroud)
在 B 和 C 列中自动填充这两个公式以获得您可能需要的最大行数(假设为 30)。
接下来,选择整个范围 (A1..C31)。转到“插入”选项卡并单击“表格”按钮将此范围更改为 Excel 表格(这些以前称为“列表”)。在“表工具设计”选项卡中,将此表的名称更改为“SalaryRanges”。
现在,转到“最小值”列中的单元格 A2,在 A3 中输入“0”、“501”、在单元格 A4 中输入“1001”,最后在单元格 A5 中输入“2001”。请注意,当您执行此操作时,会自动填充 MAx 和 Range 列。
现在制作另一个名为“Age Ranges”的新工作表,并执行与上面 #1 完全相同的步骤,除了将此表称为“AgeRanges”并在 Min 列中用 0、15、20、30 和40,按顺序。同样,Max 和 Range 值应该在您进行时自动填充。
将数据从数据库中获取到您的 Excel 工作簿中,就像您之前所做的一样(不要制作数据透视表,我们在下面这样做),除了您应该删除 AgeRange 和 SalaryRange 案例函数列。
在数据所在的工作表中,添加“SalaryRange”和“AgeRange”列。在 SalaryRange 列中,自动填充以下公式(假设“D”是 Salary 列):
=LOOKUP(D2,SalaryRanges)
Run Code Online (Sandbox Code Playgroud)
并将此公式自动填充到 AgeRange 列(假设“C”是 Age 列):
=LOOKUP(C2,AgeRanges)
Run Code Online (Sandbox Code Playgroud)
像以前一样这样做。请注意,年龄和薪水范围值/标签与您选择的范围相匹配。
现在是有趣的部分。转到 SalaryRanges 工作表并重新输入 Min 列,从 0 开始,然后是 101、201、301、... 2001。返回到数据透视表并刷新它。沙赞!
我应该提到,当然,您也可以通过将表放在 SQL 中并更改 SELECT 语句以将 LOOKUP(..)s 作为子查询来实现相同的效果(由于范围匹配而有点混乱,但绝对可以-有能力的)。我这样做的原因(在 Excel 中)是
然而,有时让用户定义他们自己的范围实际上是不可取的。如果您是这种情况,我将很乐意演示如何在 SQL 中集中进行。
小智 5
使用 MDX 语言,您可以创建将定义范围的自定义成员。以下表达式定义了一个计算成员,表示 501 到 1000 之间的所有工资:
MEMBER [Salary].[between_500_and_1000] AS Aggregate(Filter([Salary].Members, [Salary].CurrentMember.MemberValue > 500 AND [Salary].CurrentMember.MemberValue <= 1000))
Run Code Online (Sandbox Code Playgroud)
你可以用年龄维度做同样的事情:
MEMBER [Age].[between_0_and_25] AS Aggregate(Filter([Age].Members, [Age].CurrentMember.MemberValue <= 25))
Run Code Online (Sandbox Code Playgroud)
该文章介绍了如何添加论文calculted成员在Excel中(见“创建计算成员/措施,并设置在Excel 2007 OLAP数据透视表”部分)。遗憾的是,Excel 中没有用于此的 UI。尽管如此,您还是可以找到支持MDX语言的BI 客户端,它们允许在查询中定义您的范围。
| 归档时间: |
|
| 查看次数: |
10292 次 |
| 最近记录: |