Definir dinámicamente un rango en una dimensión


18

Tengo un problema que enfrento cada vez que decido construir un cubo, y todavía no he encontrado una manera de superarlo.

El problema es cómo permitir que el usuario defina una variedad de cosas automáticamente sin tener que codificarlas en la dimensión. Explicaré mi problema en un ejemplo.

Tengo una mesa llamada Clientes :

Estructura de la mesa

Estos son los datos de la tabla:

Mesa con datos

Quiero mostrar los datos en un estilo dinámico y agrupar el salario y la edad en rangos definidos como a continuación:

Tabla con datos con rango definido

Escribí este script y definí los rangos:

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

Mis rangos están codificados y definidos. Cuando copio los datos a Excel y los veo en una tabla dinámica, aparece a continuación:

Datos en la tabla dinámica

Mi problema es que quiero crear un cubo al convertir la tabla Clientes en una tabla de hechos y crear tablas de 2 dimensiones SalaryDim y AgeDim .

La tabla SalaryDim tiene 2 columnas ( SalaryKey, SalaryRange ) y la tabla AgeDim es similar ( ageKey, AgeRange ). Mi tabla de hechos del cliente tiene:

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

Todavía tengo que definir mis rangos dentro de estas dimensiones. Cada vez que conecto un pivote de Excel a mi cubo, solo puedo ver estos rangos definidos codificados.

Mi pregunta es cómo definir rangos dinámicamente desde la tabla dinámica directamente, sin crear las dimensiones de rango como AgeDim y SalaryDim . No quiero quedarme solo en los rangos definidos en la dimensión.

Sin rango definido

El rango definido es '0-25', '26 -30 ', '31 - 50'. Es posible que desee cambiarlo a '0-20', '21 -31 ', '32 -42', etc., y los usuarios solicitan diferentes rangos cada vez.

Cada vez que lo cambio, tengo que cambiar la dimensión. ¿Cómo puedo mejorar este proceso?

Sería genial tener una solución implementada en el cubo, de modo que cualquier herramienta de cliente de BI que se conecte al cubo pueda definir los rangos, pero no me importaría si hay una buena manera de usar solo Excel.

Respuestas:


12

CÓMO HACER ESTO CON T-SQL:

Según lo solicitado, esta es una alternativa a mi respuesta anterior que mostró cómo hacerlo por usuario con Excel. Esta respuesta muestra cómo hacer lo mismo compartido / centralmente usando T-SQL en su lugar. No sé cómo hacer Cubes, MDX o SSAS para esto, así que tal vez Benoit o alguien que sí sepa que puede publicar su equivalente ...

1. Agregar SalaryRanges SQL Table and View

Cree una nueva tabla llamada "SalaryRangeData" con el siguiente comando:

Create Table SalaryRangeData(MinVal INT Primary Key)

Agregue columnas calculadas envolviéndolas en una Vista con 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

Haga clic derecho en la tabla en SSMS y seleccione "Editar las 200 filas principales". Luego ingrese los siguientes valores en las celdas MinVal: 0, 501, 1001 y 2001 (el orden no importa para SQL Server, lo creará para nosotros). Cierre el editor de filas de tabla y haga una SELECT * FROM SalaryRangespara ver todas las filas y la información de rango.

2. Agregar AgeRanges SQL Table and View

Siga exactamente los mismos pasos que en el punto 1 anterior, excepto que reemplace todas las apariciones de "Salario" con "Edad". Esto debería hacer que la tabla "AgeRangeData" y la vista "AgeRanges".

Ingrese los siguientes valores en la columna AgeRangeData [MinVal]: 0, 15, 20, 30 y 40.

3. Agregar rangos a los datos

Reemplace su instrucción SELECT con expresiones CASE para recuperar los datos y rangos con la siguiente:

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. Todo lo demás, igual que ahora

De aquí en adelante, simplemente haga todo lo mismo que actualmente. Todos los rangos deberían aparecer en su tabla dinámica como lo hacen actualmente.

5. Prueba la magia

Vaya al editor de filas de tablas SalaryRangeData en SSMS nuevamente y elimine las filas existentes y luego inserte los siguientes valores: 0, 101, 201, 301, ... 2001 (nuevamente, el orden no importa para la solución T-SQL) . Regrese a su tabla dinámica y actualice los datos. Y al igual que la solución de Excel, los rangos de tabla dinámica deben cambiarse automáticamente.


Adición

CÓMO AGREGARLO A UN CUBO:

1. Crear una vista

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. Cree un proyecto de BI en Visual Studio y agregue el CustomerView

Conéctese a la base de datos y agregue la CustomerViewvista en la Data Source Viewstabla de hechos

Vistas de origen de datos

2. Cree un cubo y defina medida y dimensión

solo necesitamos customerId, como medida para el recuento de clientes y tendremos la misma tabla de hechos como dimensión

Medidas

Dimensiones

3. Agregar atributos a la dimensión

Agregar rangos como atributos a la dimensión

4. Conéctese a Cube desde Excel

Agregar fuente SSAS a Excel

Selecciona el cubo

5. Ver los datos del cubo en Excel

Ver el cubo en Excel

6. para cualquier cambio en los rangos simplemente reprocese la dimensión y el cubo

Si es necesario cambiar los rangos, cambiar los datos en el SalaryRangeDatae AgeRangeDatay luego simplemente reprocesar las dimensiones y el cubo


8

CÓMO HACER ESTO CON EXCEL

Así es como lo haría en Excel ...

1. Agregar tabla de Excel SalaryRanges

Inserte una nueva hoja de trabajo, llámela "Rangos de salario". En la fila uno, agregue los encabezados de texto "Min", "Max" y "Range" en ese orden (deben ser las celdas A1, A2, A3, respectivamente).

En la celda B2, agregue la siguiente fórmula:

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

En la celda C2 agregue esta fórmula:

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

Complete automáticamente estas dos fórmulas en las columnas B y C para obtener el número máximo de filas que pueda necesitar (digamos 30).

A continuación, seleccione todo el rango (A1..C31). Acceda a la pestaña Insertar y haga clic en el botón Tabla para cambiar este rango a una Tabla de Excel (solían llamarse "Listas"). En la pestaña Diseño de herramientas de tabla, cambie el nombre de esta tabla a "SalaryRanges".

Ahora, vaya a la celda A2 en la columna Min e ingrese "0", "501" en A3, "1001" en la celda A4 y finalmente "2001" en la celda A5. Tenga en cuenta que a medida que hace esto, las columnas MAx y Range se completan automáticamente.

2. Agregar tabla de Excel AgeRanges

Ahora haga otra nueva hoja de trabajo llamada "Rangos de edad", y siga exactamente los mismos pasos que en el n. ° 1 anterior, excepto que llame a esta tabla "Rangos de edad" y en la columna Min llene las celdas A2 a A6 con 0, 15, 20, 30 y 40, en orden. Nuevamente, los valores Máx. Y Rango deben rellenarse automáticamente a medida que avanza.

3. Obtenga los datos

Obtenga los datos de la base de datos en su libro de Excel tal como lo hizo antes (no haga la tabla dinámica todavía, lo hacemos a continuación), excepto que debe eliminar las columnas de función de caso AgeRange y SalaryRange.

4. Agregue las columnas Salario y Rango de edad a sus Datos

En la hoja donde están sus datos, agregue una columna "SalaryRange" y "AgeRange". En la columna SalaryRange, complete automáticamente la siguiente fórmula (se supone que "D" es la columna Salario):

=LOOKUP(D2,SalaryRanges)

Y complete automáticamente esta fórmula en la columna AgeRange (suponiendo que "C" es la columna Age):

=LOOKUP(C2,AgeRanges)

5. Haga su tabla dinámica

Haga esto tal como lo hizo antes. Tenga en cuenta que los valores / etiquetas de rango de edad y salario coinciden con los rangos que elija.

6. Prueba la magia

Ahora la parte divertida. Vaya a la hoja de trabajo SalarioRanges y vuelva a ingresar la columna Min, comenzando en 0, luego 101, 201, 301, ... 2001. Vuelva a su tabla dinámica y simplemente actualícela. Shazaam!


Debo mencionar que, por supuesto, también puede lograr el mismo efecto colocando las Tablas en SQL y cambiando su instrucción SELECT para hacer las BÚSQUEDAS (...) como subconsultas (un poco desordenado debido a la coincidencia de rango, pero definitivamente lo hace) poder). La razón por la que lo hice de esta manera (en Excel) es

  1. Cambiar los rangos es un poco más fácil para la mayoría de las personas. Incluso para los desarrolladores de DBA y SQL (como nosotros), esta forma es un poco más fácil solo porque está más cerca de la interfaz de usuario / resultados.
  2. Esto permite a sus usuarios cambiar sus propios rangos sin tener que molestarlo. (una gran ventaja en mi vida)
  3. Esto también permite a cada usuario definir sus propios rangos.

Sin embargo, a veces no es deseable que los usuarios definan sus propios rangos. Si ese es su caso, me complacerá demostrarle cómo hacerlo de manera centralizada, en SQL.


+1 y muchas gracias, la solución funciona de maravilla, conectando la tabla con los datos con todos los rangos en Excel. ¿Hay alguna manera de conectar estos rangos definidos con la tabla dinámica que está conectada al Cubo? Mis pivotes están directamente conectados al cubo en SSAS, y también sería genial si puedes mostrar "cómo hacerlo centralmente".
AmmarR

Puedo mostrarle cómo hacerlo centralmente con expresiones SQL, lo publicaré como una respuesta alternativa. No puedo abordar los problemas de Cube / SSAS porque desafortunadamente no los conozco. Sí, debería conocerlos y desearía hacerlo, pero no lo sé, por lo que alguien más tendrá que abordar eso.
RBarryYoung

5

Con el lenguaje MDX puede crear miembros personalizados que definirán los rangos. La siguiente expresión definió un miembro calculado que representa todos los salarios entre 501 y 1000:

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

Puedes hacer lo mismo con la dimensión de edad:

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

Este artículo explica cómo agregar estos miembros calculados en Excel (consulte la sección ' Creación de miembros / medidas calculadas y conjuntos en las tablas dinámicas OLAP de Excel 2007 '). Lamentablemente, no hay una interfaz de usuario en Excel para esto. Sin embargo, puede encontrar clientes de BI que admitan el lenguaje MDX , que permiten definir sus rangos en las consultas.


gracias @Benoit, estoy tratando de agregar campos calculados en el cubo con el mismo concepto que sugieres, pero todavía no parece funcionar, el proceso es un poco largo y no estoy familiarizado con él, lo intentaré con Excel también,
AmmarR

Gracias @RBarryYoung. @ MarkStorey-Smith: Puedo mejorar la eficiencia de la fórmula, si me da la lista de los niveles que están en la dimensión Salaryy Age.
Benoit
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.