web-dev-qa-db-ja.com

ディメンションの範囲を動的に定義する

キューブを構築することを決定するたびに直面する問題があり、それを克服する方法をまだ見つけていません。

問題は、ユーザーがディメンションにハードコードする必要なく、さまざまなものを自動的に定義できるようにする方法です。例題で問題を説明します。

Customersというテーブルがあります。

Table Structure

これは表のデータです:

Table with data

データをピボットスタイルで表示し、次のような定義された範囲でSalaryおよびAgeをグループ化します。

Table with Data with Defined Range

私はこのスクリプトを書いて範囲を定義しました:

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にコピーしてピボットテーブルで表示すると、次のように表示されます。

Data in Pivot Table

私の問題は、Customersテーブルをファクトテーブルに変換してキューブを作成し、2つのディメンションテーブルSalaryDimAgeDimを作成することです。

SalaryDimテーブルには2つの列(SalaryKey、SalaryRange)があり、AgeDimテーブルは類似しています(ageKey、AgeRange) 。私の顧客ファクトテーブルには以下が含まれます。

Customer
[CustId]
[CustName]
[AgeKey] --> foreign Key to AgeDim
[Salarykey] --> foreign Key to SalaryDim

これらのディメンション内で範囲を定義する必要があります。 Excelピボットをキューブに接続するたびに、ハードコードされた定義済みの範囲しか表示されません。

私の質問は、AgeDimSalaryDimのような範囲ディメンションを作成せずに、ピボットテーブルから直接動的に範囲を定義する方法です。ディメンションで定義された範囲だけに固執する必要はありません。

No Range Defined

定義された範囲は、「0-25」、「26-30」、「31-50」です。 「0-20」、「21-31」、「32-42」などに変更すると、ユーザーは毎回異なる範囲を要求します。

それを変えるたびに、私は次元を変えなければなりません。このプロセスを改善するにはどうすればよいですか?

キューブにソリューションを実装して、キューブに接続するどのBIクライアントツールでも範囲を定義できるようにするのは素晴らしいことですが、Excelのみを使用する良い方法があったとしてもかまいません。

18
AmmarR

T-SQLでこれを行う方法:

要求されたとおり、これはExcelでユーザーごとに実行する方法を示した私の以前の回答の代替です。この回答は、代わりにT-SQLを使用して共有/中心的に同じことを行う方法を示しています。私はこれのためにCubes、MDXまたはSSASのものをどのように行うか知りません、それでおそらくBenoitまたはそれを知っている誰かが同等のものを投稿することができます...

1. SalaryRanges SQLテーブルとビューを追加する

次のコマンドを使用して、「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を実行して、すべての行と範囲情報を表示します。

2. AgeRanges SQLテーブルとビューを追加する

上記の#1とまったく同じ手順を実行しますが、「給与」のすべての出現箇所を「年齢」に置き換えます。これにより、テーブル「AgeRangeData」とビュー「AgeRanges」が作成されます。

AgeRangeData [MinVal]列に0、15、20、30、および40の値を入力します。

3.データに範囲を追加する

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]

4.その他すべて、今と同じ

ここからは、現在と同じようにすべてを実行します。現在のように、範囲はすべてピボットテーブルに表示されます。

5.マジックをテストする

SSMSのSalaryRangeDataテーブル行エディターに再度移動し、既存の行を削除してから、次の値を挿入します:0、101、201、301、... 2001(ここでも、T-SQLソリューションでは順序は関係ありません) 。ピボットテーブルに戻り、データを更新します。また、Excelソリューションと同様に、ピボットテーブルの範囲は自動的に変更されます。


追加

キューブに追加する方法:

1.ビューを作成する

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]

1. Visual StudioでBIプロジェクトを作成し、CustomerViewを追加します

データベースに接続し、CustomerViewビューをData Source Viewsに追加して、ファクトテーブルにします。

Data Source Views

2.キューブを作成し、メジャーとディメンションを定義する

顧客数の指標として、customerIdのみが必要であり、ディメンションと同じファクトテーブルを持ちます。

Measures

Dimensions

3.ディメンションに属性を追加する

Add ranges as Attributes to the Dimension

4. Excelからキューブに接続します

Add SSAS source to Excel

Select the Cube

5. Excelでキューブのデータを表示する

View the Cube in Excel

6.範囲の変更については、ディメンションとキューブを再処理するだけです

範囲を変更する必要がある場合は、SalaryRangeDataAgeRangeDataのデータを変更してから、ディメンションとキューブを再処理します

12
RBarryYoung

Excelでこれを行う方法

Excelでこれを行う方法は次のとおりです...

1. SalaryRanges 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列が自動的に入力されます。

2. AgeRanges Excelテーブルを追加します

次に、「Age Ranges」という名前の別の新しいワークシートを作成し、上記の#1とまったく同じ手順を実行します。ただし、このテーブルを「AgeRanges」と呼び、Min列でセルA2からA6に0、15、20、30、および40、順番に。繰り返しますが、最大値と範囲値は、移動するにつれて自動的に入力されます。

3.データを取得する

AgeRangeおよびSalaryRangeケース関数列を削除する必要があることを除いて、以前と同じように(まだピボットテーブルを作成しないでください。以下で行います)、データベースからExcelブックにデータを取得します。

4.データにSalaryとAge Range列を追加します

データがあるシートで、「SalaryRange」と「AgeRange」列を追加します。 SalaryRange列で、次の数式を自動入力します(「D」がSalary列であると想定しています)。

=LOOKUP(D2,SalaryRanges)

そして、この数式をAgeRange列に自動入力します( "C"がAge列であると想定)。

=LOOKUP(C2,AgeRanges)

5.ピボットテーブルを作成する

以前と同じようにこれを行います。年齢と給与の範囲の値/ラベルは、選択した範囲と一致することに注意してください。

6.マジックをテストする

楽しい部分です。 SalaryRangesワークシートに移動し、0から始めて、次に101、201、301、... 2001のようにMin列を再入力します。ピボットテーブルに戻り、更新します。シャザム!


もちろん、TablesをSQLに入れ、LOOKUP(..)をサブクエリとして実行するようにSELECTステートメントを変更することで、同じ効果を実現することもできます(範囲が一致しているため少し面倒ですが、間違いなくできる)。私がこのように(Excelで)それをした理由は

  1. 範囲の変更は、ほとんどの人にとって少し簡単です。 DBAやSQL開発者(私たちのような)にとっても、UI /結果に近いため、この方法は少し簡単です。
  2. これにより、ユーザーは煩わされることなく自分の範囲を変更できます。 (私の人生の大きなプラス)
  3. これにより、各ユーザーが独自の範囲を定義することもできます。

ただし、ユーザーが独自の範囲を定義することは、実際には望ましくないである場合があります。それが当てはまる場合は、代わりにSQLで集中的に行う方法を示すことができます。

8
RBarryYoung

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クライアントを見つけることができます。

5
Benoit