Definir dinamicamente um intervalo em uma dimensão

18

Tenho um problema que enfrento toda vez que decido construir um cubo e ainda não encontrei uma maneira de superá-lo.

A questão é como permitir que o usuário defina uma série de coisas automaticamente, sem a necessidade de codificá-las na dimensão. Vou explicar meu problema em um exemplo.

Eu tenho uma tabela chamada Customers :

Estrutura da tabela

estes são os dados na tabela:

Tabela com dados

Eu quero exibir os dados em um estilo dinâmico e agrupar o salário e a idade em intervalos definidos, como abaixo:

Tabela com dados com intervalo definido

Eu escrevi este script e defini os intervalos:

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

Meus intervalos são codificados e definidos. Quando copio os dados para o Excel e os vejo em uma tabela dinâmica, eles aparecem como abaixo:

Dados na tabela dinâmica

Meu problema é que eu quero criar um cubo convertendo a tabela Customers em uma tabela de fatos e criar 2 tabelas de dimensão SalaryDim & AgeDim .

A tabela SalaryDim possui 2 colunas ( SalaryKey, SalaryRange ) e a tabela AgeDim é semelhante ( ageKey, AgeRange ). A tabela de fatos Meu cliente possui:

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

Ainda tenho que definir meus intervalos dentro dessas dimensões. Sempre que conecto um pivô do Excel ao meu cubo, só consigo ver esses intervalos definidos codificados.

Minha pergunta é como definir intervalos dinamicamente diretamente da tabela dinâmica, sem criar as dimensões do intervalo, como AgeDim e SalaryDim . Não quero ficar preso apenas aos intervalos definidos na dimensão.

Sem intervalo definido

O intervalo definido é '0-25', '26 -30 ', '31 - 50'. Talvez eu queira alterá-lo para '0-20', '21 -31 ', '32 -42' e assim por diante, e os usuários solicitam intervalos diferentes a cada vez.

Toda vez que eu mudo, tenho que mudar a dimensão. Como posso melhorar esse processo?

Seria ótimo ter uma solução implementada no cubo, para que qualquer ferramenta de cliente de BI que se conecta ao cubo possa definir os intervalos, mas não me importaria se existe uma boa maneira de usar somente o Excel.

AmmarR
fonte

Respostas:

12

COMO FAZER ISSO COM T-SQL:

Conforme solicitado, essa é uma alternativa à minha resposta anterior, que mostrou como fazer isso por usuário com o Excel. Esta resposta mostra como fazer a mesma coisa compartilhada / centralmente usando o T-SQL. Eu não sei como fazer cubos, MDX ou o SSAS para isso, então talvez Benoit ou alguém que saiba que pode postar seu equivalente ...

1. Adicionar tabela e exibição SQL SalaryRanges

Crie uma nova tabela chamada "SalaryRangeData" com o seguinte comando:

Create Table SalaryRangeData(MinVal INT Primary Key)

Adicione colunas calculadas envolvendo-as em uma View com este comando:

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

Clique com o botão direito do mouse na tabela no SSMS e selecione "Editar as 200 principais linhas". Em seguida, insira os seguintes valores nas células MinVal: 0, 501, 1001 e 2001 (o pedido não importa para o SQL Server, ele será criado para nós). Feche o editor de linhas da tabela e faça um SELECT * FROM SalaryRangespara ver todas as linhas e informações sobre o intervalo.

2. Adicione tabela e exibição SQL AgeRanges

Execute exatamente as mesmas etapas do item 1 acima, exceto substitua todas as ocorrências de "Salário" por "Idade". Isso deve tornar a tabela "AgeRangeData" e a exibição "AgeRanges".

Digite os seguintes valores na coluna AgeRangeData [MinVal]: 0, 15, 20, 30 e 40.

3. Adicionar intervalos aos dados

Substitua sua instrução SELECT pelas expressões CASE para recuperar os dados e intervalos pelo seguinte:

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. Tudo o resto, o mesmo que agora

A partir daqui, faça tudo da mesma forma que você é atualmente. Todos os intervalos devem aparecer na sua Tabela Dinâmica como atualmente.

5. Teste a magia

Vá para o editor de linhas da tabela SalaryRangeData no SSMS novamente e exclua as linhas existentes e insira os seguintes valores: 0, 101, 201, 301, ... 2001 (novamente, a ordem não importa para a solução T-SQL) . Volte para a tabela dinâmica e atualize os dados. E, assim como a solução do Excel, os intervalos da Tabela Dinâmica devem ser alterados automaticamente.


Adição

COMO ADICIONAR A UM CUBO:

1. Crie uma visão

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. Crie um projeto de BI no Visual studio e adicione o CustomerView

Conecte-se ao banco de dados e adicione a CustomerViewexibição na Data Source Viewstabela a ser o fato

Exibições da fonte de dados

2. Crie um cubo e defina Medida e dimensão

precisamos apenas de customerId, como uma medida para a contagem de clientes e teremos a mesma tabela de fatos que uma dimensão

Medidas

Dimensões

3. Adicione atributos à dimensão

Adicionar intervalos como atributos à dimensão

4. Conecte-se ao cubo a partir do Excel

Adicionar fonte SSAS ao Excel

Selecione o cubo

5. Visualize os dados do cubo no Excel

Exibir o cubo no Excel

6. para Quaisquer alterações nas escalas apenas reprocessam o Dimension & cube

se você precisar alterar os intervalos, alterar os dados no SalaryRangeDatae AgeRangeDataem seguida, basta reprocessar as dimensões e o cubo

RBarryYoung
fonte
8

COMO FAZER ISSO COM EXCEL

Aqui está como eu faria isso no Excel ...

1. Adicionar tabela SalaryRanges Excel

Insira uma nova planilha, chame-a de "Salário". Na linha um, adicione os cabeçalhos de texto "Min", "Max" e "Range" nessa ordem (devem ser as células A1, A2, A3, respectivamente).

Na célula B2, adicione a seguinte fórmula:

=IF(A2="","",IF(A3="","+",A3-1))

Na célula C2, adicione esta fórmula:

=IF(B2="","",A2 & IF(B2="+",""," - ") & B2)

Preencher automaticamente essas duas fórmulas nas colunas B e C para o número máximo de linhas que você pode precisar (digamos 30).

Em seguida, selecione o intervalo inteiro (A1..C31). Acesse a guia Inserir e clique no botão Tabela para alterar esse intervalo para uma Tabela do Excel (que costumava ser chamada de "Listas"). Na guia Design das ferramentas de tabela, altere o nome desta tabela para "SalaryRanges".

Agora, vá para a célula A2 na coluna Mín e digite "0", "501" em A3, "1001" na célula A4 e, finalmente, "2001" na célula A5. Observe que, ao fazer isso, as colunas MAx e Range são preenchidas automaticamente.

2. Adicione a tabela AgeRanges Excel

Agora crie outra nova planilha denominada "Faixas etárias" e execute exatamente as mesmas etapas do item 1 acima, exceto chamar esta tabela "Faixas etárias" e, na coluna Min, preencha as células A2 a A6 com 0, 15, 20, 30 e 40, em ordem. Novamente, os valores Max e Range devem ser preenchidos automaticamente conforme você avança.

3. Obtenha os dados

Obtenha os dados do banco de dados na sua pasta de trabalho do Excel, como você fez antes (não faça a Tabela Dinâmica ainda, fazemos isso abaixo), exceto que você deve remover as colunas das funções de caso AgeRange e SalaryRange.

4. Adicione as colunas Salário e Faixa etária aos seus Dados

Na planilha onde estão seus dados, adicione as colunas "SalaryRange" e "AgeRange". Na coluna SalaryRange, preencha automaticamente a seguinte fórmula (pressupõe que "D" é a coluna Salary):

=LOOKUP(D2,SalaryRanges)

E preencha automaticamente esta fórmula na coluna AgeRange (supondo que "C" seja a coluna Age):

=LOOKUP(C2,AgeRanges)

5. Crie sua Tabela Dinâmica

Faça isso exatamente como você fez antes. Observe que os valores / rótulos de faixa etária e de salário correspondem aos intervalos que você escolher.

6. Teste a mágica

Agora a parte divertida. Vá para a planilha SalaryRanges e digite novamente a coluna Min, começando em 0, depois em 101, 201, 301, ... 2001. Volte para a Tabela Dinâmica e atualize-a. Shazaam!


Devo mencionar que é claro que você também pode obter o mesmo efeito colocando as tabelas no SQL e alterando sua instrução SELECT para executar as LOOKUP (..) s como subconsultas (um pouco confuso por causa da correspondência de intervalo, mas definitivamente capaz). O motivo pelo qual fiz dessa maneira (no Excel) é

  1. Alterar os intervalos é um pouco mais fácil para a maioria das pessoas. Mesmo para desenvolvedores de DBA e SQL (como nós), esse caminho é um pouco mais fácil, apenas porque está mais próximo da interface do usuário / resultados.
  2. Isso permite que seus usuários alterem seus próprios intervalos sem ter que incomodá-lo. (uma grande vantagem na minha vida)
  3. Isso também permite que cada usuário defina seus próprios intervalos.

No entanto, às vezes é realmente indesejável que os usuários definam seus próprios intervalos. Se esse for o seu caso, ficarei feliz em demonstrar como fazê-lo centralmente, no SQL.

RBarryYoung
fonte
+1 e muito obrigado a solução funciona de maneira incrível, conectando a tabela aos dados com os intervalos no excel. Existe uma maneira de conectar esses intervalos definidos à tabela dinâmica conectada ao cubo, meus eixos dinâmicos estão diretamente conectados ao cubo no SSAS, e também seria ótimo se você pudesse mostrar "como fazer isso centralmente".
AmmarR
Eu posso mostrar como fazer isso centralmente com expressões SQL; postarei isso como uma resposta alternativa. Não consigo resolver os problemas do Cube / SSAS porque, infelizmente, não os conheço. Sim, eu deveria conhecê-los e gostaria de conhecê-lo, mas não conheço, para que outra pessoa precise resolver isso.
precisa saber é o seguinte
5

Com a linguagem MDX, você pode criar membros personalizados que definirão os intervalos. A expressão a seguir definiu um membro calculado que representa todos os salários entre 501 e 1000:

MEMBER [Salary].[between_500_and_1000] AS Aggregate(Filter([Salary].Members, [Salary].CurrentMember.MemberValue > 500 AND [Salary].CurrentMember.MemberValue <= 1000))

Você pode fazer o mesmo com a dimensão da idade:

MEMBER [Age].[between_0_and_25] AS Aggregate(Filter([Age].Members, [Age].CurrentMember.MemberValue <= 25))

Este artigo explica como adicionar membros calculados a teses no Excel (consulte a seção ' Criando membros / medidas e conjuntos calculados nas tabelas dinâmicas OLAP do Excel 2007 '). Infelizmente, não há interface do usuário no Excel para isso. No entanto, você pode encontrar clientes de BI compatíveis com a linguagem MDX , que permitem definir seus intervalos nas consultas.

Benoit
fonte
obrigado @Benoit, estou tentando adicionar campos calculados no cubo com o mesmo conceito que você está sugerindo, mas eu não parece funcionar ainda, o processo é um pouco demorado e não estou familiarizado com ele, tentarei com o excel bem,
AmmarR
Obrigado @RBarryYoung. @ MarkStorey-Smith: Eu posso melhorar a eficiência da fórmula, se você me der a lista dos níveis que estão na dimensão Salarye Age.
Benoit