No pude pensar en un mejor título para esta entrada, pero estoy seguro de que debe haber un mejor término para lo que estoy escribiendo… De todos modos, la solución original que publiqué para obtener los nombres de los miembros actuales en todos los mensajes de la semana pasada El problema de las dimensiones me recordó a algunos MDX que se me ocurrieron el año pasado, para la compartimentación dinámica. Con eso me refiero a la capacidad de ejecutar consultas en MDX donde puede contar (o sumar, o lo que sea) los miembros que se encuentran dentro de rangos definidos dinámicamente. Imagina que eres el gerente de las tiendas Foodmart 2000 y quieres ver un gráfico de barras que muestre la cantidad de categorías de productos con ventas entre $0 y $500, $500 y $1000, $1000 y $1500, etc. (cada uno de estos rangos son los ‘cubos’ del título). Ahora, en AS2K, el enfoque estándar sería crear estos miembros calculados manualmente en el cubo o en la cláusula WITH, lo que lleva mucho tiempo si tiene muchos depósitos. Pero, ¿qué sucede si desea un informe con este histograma en el que pueda establecer dinámicamente la cantidad de depósitos y el rango que contiene cada depósito? ¡Esto hace las cosas aún más difíciles!

Aquí está mi solución en una consulta de Foodmart 2000:

CON
/*PRIMERO DEFINE EL TAMAÑO DE CADA CUBO*/
MEDIDAS DE LOS MIEMBROS. TAMAÑO COMO ‘500’
/*SIGUIENTE, ELIJA UN NIVEL DE DIMENSIÓN QUE NO UTILICE EN SUS CONSULTAS Y TENGA MÁS
MIEMBROS SEGÚN NÚMERO DE CUBOS QUE QUIERAS. LUEGO DEFINE UN CONJUNTO CON EL MISMO NÚMERO
DE MIEMBROS EN EL NÚMERO DE CUBO DESEADO*/
ESTABLECER BUCKETHACK COMO ‘CABEZA([Promotions].[Promotion Name].MIEMBROS, 10)’
/*ENTONCES, CREAR UN MIEMBRO CALCULADO QUE ENCUENTRE EL RANGO DEL MIEMBRO ACTUAL EN EL CONJUNTO QUE SE ACABA DE CREAR*/
MEDIDAS DE LOS MIEMBROS. CLASIFICACIÓN COMO ‘RANGO ([Promotions].MIEMBRO ACTUAL, BUCKETHACK) – 1’
/* AHORA USA LA FUNCIÓN CREATEPROPERTYSET PARA CREAR UN CONJUNTO DE MIEMBROS CALCULADOS QUE REPRESENTAN
LOS CUBOS. EL NOMBRE DE CADA MIEMBRO CALCULADO SE DERIVA DEL RANGO DE CADA MIEMBRO DE LA ASAMBLEA BUCKETHACK
ESTOY UTILIZANDO LA DIMENSIÓN DE CLIENTES AQUÍ, PERO DEBE UTILIZAR UNA NUEVA DIMENSIÓN CREADA ESPECÍFICAMENTE PARA ESTE FIN
CON UN SOLO MIEMBRO TODOS*/
ESTABLECER MYBUCKETS COMO ‘CREATEPROPERTYSET([Customers].[All Customers]balde,
«$» + CSTR(MEDIDAS.CLASIFICACIÓN * MEDIDAS.TAMAÑO) + » – $» + CSTR((MEDIDAS.CLASIFICACIÓN+1) * MEDIDAS.TAMAÑO))’
/*LUEGO CREAR UNA NUEVA MEDIDA CALCULADA QUE ENCUENTRE EL RANGO DEL CUBO ACTUAL DE LA LISTA DE TODOS LOS CUBO
PARA FACILITAR LA LECTURA DEL MDX*/
MEDIDAS DE LOS MIEMBROS.RANKING2 AS ‘RANK(CLIENTES.MIEMBRO ACTUAL, MYBUCKETS)-1’
/*Y FINALMENTE CREAR UNA NUEVA MEDIDA CALCULADA QUE CUENTE EL NÚMERO DE CATEGORÍAS DE PRODUCTOS EN CADA CUBO*/
MEDIDAS DE LOS MIEMBROS.[PROD CAT COUNT] COMO ‘CONTAR(
FILTRADO([Product].[Product Category].MIEMBROS,
(LAS MEDIDAS.[UNIT SALES], [Customers].[All Customers])>=(MEDIDAS.RANKING2*MEDIDAS.TAMAÑO)
Y
(LAS MEDIDAS.[UNIT SALES], [Customers].[All Customers])<((MEDIDAS.RANKING2+1)*MEDIDAS.TAMAÑO)
))’
/* SOLO PARA MOSTRAR QUÉ MIEMBROS CAEN EN CUAL CUBO */
MEDIDAS DE LOS MIEMBROS.[BUCKET MEMBERS] COMO ‘GENERAR(
FILTRADO([Product].[Product Category].MIEMBROS,
(LAS MEDIDAS.[UNIT SALES], [Customers].[All Customers])>=(MEDIDAS.RANKING2*MEDIDAS.TAMAÑO)
Y
(LAS MEDIDAS.[UNIT SALES], [Customers].[All Customers])<((MEDIDAS.RANKING2+1)*MEDIDAS.TAMAÑO)
), PRODUCTO.ACTUAL.NÚMERO DE MIEMBRO, «, «)’
/*LA SOLICITUD DE DEMO*/
SELECCIONE {MEDIDAS.RANKING2, MEDIDAS.[PROD CAT COUNT]LAS MEDIDAS.[BUCKET MEMBERS]} EN 0,
MIS CUBOS EN 1
VENTAS

Puede adaptar este MDX para otros tipos de análisis similares (me vienen a la mente las curvas de Pareto) y sospecho que esto sería útil en situaciones en las que la generación dinámica de la consulta en sí es difícil o imposible, como en un informe de Reporting Services.

Admito que no es elegante, pero pensé que aún era interesante y que valía la pena compartirlo. Maneja el problema del conteo dinámico de cubos con el mismo método que MDX la semana pasada: simula un ciclo for/next creando un conjunto con un número dado de miembros y luego usando GENERATE para iterar sobre él. Por supuesto, esto adolece de la necesidad de tener un nivel con al menos tantos miembros como iteraciones necesites. Luego maneja el problema de la creación dinámica de miembros calculados para cada uno de los depósitos mediante la función MDX no documentada CREATEPROPERTYSET. Espero que haya soluciones mucho mejores para ambos problemas en el Yukón. Supongo que un procedimiento almacenado haría el trabajo, pero no estoy seguro.