キューブを構築することを決定するたびに直面する問題があり、それを克服する方法をまだ見つけていません。
問題は、ユーザーがディメンションにハードコードする必要なく、さまざまなものを自動的に定義できるようにする方法です。例題で問題を説明します。
Customersというテーブルがあります。
これは表のデータです:
データをピボットスタイルで表示し、次のような定義された範囲でSalaryおよびAgeをグループ化します。
私はこのスクリプトを書いて範囲を定義しました:
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
私の範囲はハードコードされ、定義されています。データをExcelにコピーしてピボットテーブルで表示すると、次のように表示されます。
私の問題は、Customersテーブルをファクトテーブルに変換してキューブを作成し、2つのディメンションテーブルSalaryDim&AgeDimを作成することです。
SalaryDimテーブルには2つの列(SalaryKey、SalaryRange)があり、AgeDimテーブルは類似しています(ageKey、AgeRange) 。私の顧客ファクトテーブルには以下が含まれます。
Customer
[CustId]
[CustName]
[AgeKey] --> foreign Key to AgeDim
[Salarykey] --> foreign Key to SalaryDim
これらのディメンション内で範囲を定義する必要があります。 Excelピボットをキューブに接続するたびに、ハードコードされた定義済みの範囲しか表示されません。
私の質問は、AgeDimやSalaryDimのような範囲ディメンションを作成せずに、ピボットテーブルから直接動的に範囲を定義する方法です。ディメンションで定義された範囲だけに固執する必要はありません。
定義された範囲は、「0-25」、「26-30」、「31-50」です。 「0-20」、「21-31」、「32-42」などに変更すると、ユーザーは毎回異なる範囲を要求します。
それを変えるたびに、私は次元を変えなければなりません。このプロセスを改善するにはどうすればよいですか?
キューブにソリューションを実装して、キューブに接続するどのBIクライアントツールでも範囲を定義できるようにするのは素晴らしいことですが、Excelのみを使用する良い方法があったとしてもかまいません。
要求されたとおり、これはExcelでユーザーごとに実行する方法を示した私の以前の回答の代替です。この回答は、代わりにT-SQLを使用して共有/中心的に同じことを行う方法を示しています。私はこれのためにCubes、MDXまたはSSASのものをどのように行うか知りません、それでおそらくBenoitまたはそれを知っている誰かが同等のものを投稿することができます...
次のコマンドを使用して、「SalaryRangeData」という新しいテーブルを作成します。
Create Table SalaryRangeData(MinVal INT Primary Key)
次のコマンドでビューにラップして、計算された列を追加します。
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
SSMSでテーブルを右クリックし、[上位200行の編集]を選択します。次に、MinValセルに次の値を入力します:0、501、1001、および2001(SQL Serverでは順序は関係ありません。作成されます)。テーブル行エディターを閉じ、SELECT * FROM SalaryRanges
を実行して、すべての行と範囲情報を表示します。
上記の#1とまったく同じ手順を実行しますが、「給与」のすべての出現箇所を「年齢」に置き換えます。これにより、テーブル「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]
ここからは、現在と同じようにすべてを実行します。現在のように、範囲はすべてピボットテーブルに表示されます。
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]
CustomerView
を追加しますデータベースに接続し、CustomerView
ビューをData Source Views
に追加して、ファクトテーブルにします。
顧客数の指標として、customerIdのみが必要であり、ディメンションと同じファクトテーブルを持ちます。
範囲を変更する必要がある場合は、SalaryRangeData
とAgeRangeData
のデータを変更してから、ディメンションとキューブを再処理します
Excelでこれを行う方法は次のとおりです...
新しいワークシートを挿入し、「給与範囲」と呼びます。 1行目に、テキストヘッダー「Min」、「Max」、「Range」をこの順序で追加します(それぞれセルA1、A2、A3である必要があります)。
セルB2に次の数式を追加します。
=IF(A2="","",IF(A3="","+",A3-1))
セルC2に次の数式を追加します。
=IF(B2="","",A2 & IF(B2="+",""," - ") & B2)
これら2つの数式をB列とC列に自動入力して、必要になる可能性のある最大行数(30とする)を取得します。
次に、範囲全体(A1..C31)を選択します。 [挿入]タブに移動し、[テーブル]ボタンをクリックして、この範囲をExcelのテーブル(以前は「リスト」と呼ばれていました)に変更します。 [テーブルツールのデザイン]タブで、このテーブルの名前を "SalaryRanges"に変更します。
次に、Min列のセルA2に移動し、「0」、「A1」に「501」、セルA4に「1001」、セルA5に「2001」と入力します。これを行うと、MAx列とRange列が自動的に入力されます。
次に、「Age Ranges」という名前の別の新しいワークシートを作成し、上記の#1とまったく同じ手順を実行します。ただし、このテーブルを「AgeRanges」と呼び、Min列でセルA2からA6に0、15、20、30、および40、順番に。繰り返しますが、最大値と範囲値は、移動するにつれて自動的に入力されます。
AgeRangeおよびSalaryRangeケース関数列を削除する必要があることを除いて、以前と同じように(まだピボットテーブルを作成しないでください。以下で行います)、データベースからExcelブックにデータを取得します。
データがあるシートで、「SalaryRange」と「AgeRange」列を追加します。 SalaryRange列で、次の数式を自動入力します(「D」がSalary列であると想定しています)。
=LOOKUP(D2,SalaryRanges)
そして、この数式をAgeRange列に自動入力します( "C"がAge列であると想定)。
=LOOKUP(C2,AgeRanges)
以前と同じようにこれを行います。年齢と給与の範囲の値/ラベルは、選択した範囲と一致することに注意してください。
楽しい部分です。 SalaryRangesワークシートに移動し、0から始めて、次に101、201、301、... 2001のようにMin列を再入力します。ピボットテーブルに戻り、更新します。シャザム!
もちろん、TablesをSQLに入れ、LOOKUP(..)をサブクエリとして実行するようにSELECTステートメントを変更することで、同じ効果を実現することもできます(範囲が一致しているため少し面倒ですが、間違いなくできる)。私がこのように(Excelで)それをした理由は
ただし、ユーザーが独自の範囲を定義することは、実際には望ましくないである場合があります。それが当てはまる場合は、代わりにSQLで集中的に行う方法を示すことができます。
MDX言語を使用すると、範囲を定義するカスタムメンバーを作成できます。次の式は、501から1000までのすべての給与を表す計算されるメンバーを定義しています。
MEMBER [Salary].[between_500_and_1000] AS Aggregate(Filter([Salary].Members, [Salary].CurrentMember.MemberValue > 500 AND [Salary].CurrentMember.MemberValue <= 1000))
年齢ディメンションでも同じことができます。
MEMBER [Age].[between_0_and_25] AS Aggregate(Filter([Age].Members, [Age].CurrentMember.MemberValue <= 25))
この 記事 は、これらの計算されたメンバーをExcelで追加する方法を説明します( '計算されたメンバー/メジャーとセットをExcel 2007で作成するOLAPピボットテーブル' セクション)。残念ながら、このためのExcelのUIはありません。それでも、クエリで範囲を定義できる[〜#〜] mdx [〜#〜]言語をサポートするBIクライアントを見つけることができます。