Viendo productos sin venta en los último X meses con MDX

Posted by Miguel Egea | Posted in Analisys Services, MDX | Posted on 18-07-2010

1

Haca unos dias, un amigo, y alumno de un curso de MDX que impartí lanzaba esa pregunta en los post, ¿como saber los artículos que no han tenido venta en los últimos tres meses. Para eso hace falta saber que dia es hoy, aunque en realidad, me parece que es mejor olvidarse de que dia es hoy y hacerlo genérico. Vamos a ver como podriamos hacer eso.

Bueno, vamos a ir por partes.. lo primero que vamos a hacer es ver como calcular el día de hoy.

with member hoy
as
 now()
select hoy on 0
from [Adventure Works]

despues vamos a ver como sacar el conjunto de articulos con ventas en un mes.

select  exists([Product].[Product].product*[Date].[Calendar].[Month].members,,
		  "Internet Sales")
  on 1,
        {Measures.[Internet Sales Amount]} on 0
from  [Adventure Works];

el conjunto que forman los meses y  los productos que han tenido ventas es lo que nos devuelve la clasula de arriba.

Ahora vamos a calcular los que no han tenido ventas en absoluto, para ello simplemente hacemos una resta de conjuntos, es decir, todos los productos menos los que han tenido ventas

select  [Product].[Product].product*[Date].[Calendar].[Month].members-
exists([Product].[Product].product*[Date].[Calendar].[Month].members,,
		  "Internet Sales")
  on 1,
        {Measures.[Internet Sales Amount]} on 0
from  [Adventure Works];
 

De esta forma tenemos los articulos sin ventas en un mes concreto, porque son aquellos que no tienen datos en el grupo de medidas Internet Sales, para el mes en cuestion. El problema viene porque ahora necesitamos saber los que no tienen ventas en los últimos tres meses. Para poder usar Exist, necesitariamos tener un grupo especial que tuviese en el mes actual las ventas de los últimos tres meses para cada producto y comprobar su existencia. El resultado sería rápido, pero parece que quedaría bastante engorroso de hacer, además implica cambios en el ETL y eso siempre quiere decir, mucho tiempo, muchas pruebas. Así pues dejamos esta via solamente para el caso de que el rendimiento no se corresponda con el necesario. En otro caso pasamos al plan B y usamos el método filter.

	select
	filter ( [Product].[Product].product*
				[Date].[Calendar].[Month].members  ,
				 sum(([Date].[Calendar].currentmember.lag(3):[Date].[Calendar].currentmember),Measures.[Internet Sales Amount])>0) on 1,
				Measures.[Internet Sales Amount] on 0
	from  [Adventure Works];

si nos fijamos he usado la cláusula Sum para el filter, esto penalizará rendimiento, sin duda,.. considerad hacer esta medida física aun si es en el mismo grupo de medidas para mejorar el rendimiento. Aún este ejemplo nos está mostrando los que si tienen ventas en los últimos 3 meses.. veamos los que no… creo que se vé facil, si has llegado hasta aquí :)

	select [Product].[Product].product*[Date].[Calendar].[Month].members -
	filter ( [Product].[Product].product*
				[Date].[Calendar].[Month].members  ,
				 sum(([Date].[Calendar].currentmember.lag(3):[Date].[Calendar].currentmember),Measures.[Internet Sales Amount])>0) on 1,
				Measures.[Internet Sales Amount] on 0
	from  [Adventure Works]

Esta consulta tardó casi 15 segundos (una barvaridad) en mi portatil contra adventure works, si la personalizamos a un único mes.. tardará mucho menos, claro.

	select [Product].[Product].product-
	filter ( [Product].[Product].product
				,
				 sum(([Date].[Calendar].currentmember.lag(3):[Date].[Calendar].currentmember),Measures.[Internet Sales Amount])>0) on 1,
				Measures.[Internet Sales Amount] on 0
	from  [Adventure Works]
	 where
	[Date].[Calendar].[Month].&[2004]&[7]

y si ahora lo enlazamos con el now que veiamos al principio.. (ojo , no funcionará a menos que le pongas el reloj al server a un valor que de un miembro válido) Además ojo con usar STRTOMEMBER, que puede dar también problemas de rendimiento, no en este ejemplo.. pero si en general

with member ahora as
    "[Date].[Calendar].[Month].&[" +cstr(year(now()))+ "]&["+cstr(month(now()))+"]"
	select [Product].[Product].product-
	filter ( [Product].[Product].product
				,
				 sum(([Date].[Calendar].currentmember.lag(3):[Date].[Calendar].currentmember),Measures.[Internet Sales Amount])>0) on 1,
				Measures.[Internet Sales Amount] on 0
	from  [Adventure Works]
	 where
	strtomember(ahora)

Training Kit R2 listo en la web

Posted by Miguel Egea | Posted in Analisys Services, Noticias, Relacional | Posted on 14-06-2010

0

Algunos de mis compañeros en Solid han trabajado duro en esto, pero ya está listo para descarga en: http://go.microsoft.com/?linkid=9710868

esto lo dejo en inglés porque el video estará en inglés :)

Or if you just want to see what’s in it, you can preview training kit content online in the SQL Server 2008 R2 Learning Center on Channel 9 at http://channel9.msdn.com/learn/courses/SQL2008R2TrainingKit

Mi charla ayer en SecondNug, está lista.

Posted by Miguel Egea | Posted in Analisys Services, Noticias | Posted on 02-06-2010

0

Te la puedes descargar de la web del grupo  y si lo que quieres es únicamente verla,  puedes ir a esta otra dirección.

Ayer al final la demo la truqué un poquito, seguramente muchos no lo notarían si no lo dijera.. pero no se trata de dejar medias verdades. Durante el día de hoy o mañana intentaré grabar un video sobre como configurar el proactive Caching y lo mostraré en una demo en video :)

Charla en Second Nug el 1 de Junio

Posted by Miguel Egea | Posted in Analisys Services | Posted on 19-05-2010

0

El proximo 1 de Junio estaré dando una charla en directo sobre Analisys Services. La charla es On-Line en Second-Nug, uno de los grupos de usuarios on-line más activos y con mayor presencia. Mis compañeros de Solid Quality, Eladio y Salva ya han estado hablando de TSQL y SSIS y ahora me toca a  mi hablar de Analisys Services y de las diferencias entre el modelo tradicional y otro tipo de aproximaciones a proyectos multidimensionales.

Espero que os resulte de interes

http://www.secondnug.com/EventosDesarrollo/tabid/57/Default.aspx

Pruebas unitarias en proyectos multidimensionales

Posted by Miguel Egea | Posted in Analisys Services, Noticias, Relacional | Posted on 13-04-2010

1

Mi compañero en SolidQ Italia, Davide Mauri ha desarrollado un proyecto que me parece muy positivo.  Este es el mensaje que ha puesto Davide.

Y aquí puedes llegar al proyecto

A project that allow the execution of Unit Testing against a database (Relational or Multidimensional).
It uses NUnit (http://www.nunit.org/) )as unit-testing framework and does not require DBA or BI Developer to know anything about .NET: just write your SQL or MDX queries and test them. QueryUnit will take care of automatically create the assembly that will test your query for you, using NVelocity (http://nvelocity.codeplex.com/) to generate .NET classes and the CodeDom engine to compile them at runtime.

Guía de Rendimiento para Analisys Services 2008

Posted by Miguel Egea | Posted in Analisys Services | Posted on 08-03-2010

0

La descarga que tenéis aquí es una guía práctica de rendimiento en Analisys Services 2008.

Espero que la disfruteis

Perspectivas en Analisys Services, ¿lo que las vistas al Engine?

Posted by Miguel Egea | Posted in Analisys Services | Posted on 28-02-2010

0

Introducción

Las perspectivas podrían ser lo más parecido a lo que las vistas  son a relacional, Sin embargo no es ni siquiera una buena comparación. Como casi siempre que se intentan buscar analogías Relacional vs Multidimensional las comparaciones son imprecisas incompletas y no solo no ayudan a entender el segundo sino que quizá limitan una visión que ha de ser más amplia. De ahí el título de este post, no, no son lo que las vistas al Engine, porque son simplemente otra cosa, aunque de alguna forma no es descabellado asemejarlas.

¿Entonces que son las perspectivas? Las perspectivas son una forma de mostrar un subconjunto de atributos, dimensiones, medidas como si fuesen un nuevo cubo, pero ojo, no son un mecanismo de seguridad, es decir, limitan lo que se vé basicamente para que usuarios menos abezados no se líen, pero no implica en ningun caso que se limite el acceso al cubo del que son base.

La creación de perspectivas es realmente sencilla, muy muy sencilla. En nuestro proyecto de Analisys services iremos a la pestaña perspectivas como puede verse en la siguiente imagen.

Elegimos esa pestaña y creamos una nueva perspectiva. Ahí nos aparece una lista con todos los objetos de nuestro cubo.  Simplementemarcamos con checks los objetos  que quermos que se vean o dejamos desmarcados los que no queremos que aparezcan, insisto que esto no es un mecanismo de seguridad.

Una vez creadas y desplegado el cubo los usuarios perciben las perpestivas como si fuesen un nuevo cubo. Cuando nos conectamos desde un cliente observaremos algo así

Como podeis ver se ven como si fuesen un cubo mas, pero aparece el literal perspectiva.  En cualquier caso se persibe igual que si fuese un cubo.

En otros post veremos como limitar acceso por seguridad.

Ciclo de WebCast sobre SQL Server 2008 R2 (AKA Kilimanjaro)

Posted by Miguel Egea | Posted in Analisys Services, Noticias, Relacional | Posted on 24-02-2010

0

Creo que un ciclo de conferencias tan interesante y tan elaborado merecen un link mas largo, explicando que encontrar en cada uno de ellos etc.. lo haremos espero con tiempo. De momento, aquí teneis el link
Ciclo de WebCast sobre SQL Server 2008 R2 en castellano

Creando una dimensión tiempo en Analisys Services 2/2

Posted by Miguel Egea | Posted in Analisys Services | Posted on 23-01-2010

2

En el artículo anterior de la serie vimos omo  crear la primera parte de la dimensión tiempo. En este momento tenemos ya constrido nuestro DataSource View y vamos a ver como se construye nuestra dimensión tiempo desde el punto de vista de Analisys Services. Para ello empezamos con nuestro BIDS (Bussiness Intelligence Development Studio) abierto con el proyecto tal y como lo teníamos al final del artículo anterior.

Cabe destacar que estamos haciendo este proyecto con SQL Server 2008, cambia algo con respecto de 2005, así que no es de extrañar que los menús no sean exactamente los mismos, aunque si que lo es el concepto y la forma de hacerlo.

Para comenzar pulsaremos sobre el apartado dimensiones con el botón derecho, eligiendo la opción Nueva dimensión, en ese instante nos aparecerá el asistente para la creación de dimensiones, y tras saltarnos si procede la página de bienvenida, elegiremos la opción “Use an existing table”, Usar una tabla existente. (Aunque hay opciones para crear una tabla de tiempo en el origen de datos o en el servidor, y que estas opciones puedan resultar muy atractivas a simple vista, nosotros vamos a usar la forma máal de  crear todo lo relacionado con la dimensión tiempo, porque nuestro objetivo es entenderlo. Además, al menos yo, siempre uso el mecanísmo que estoy describiendo, porque no me aporta un trabajo extra y si me da un control muy importante sobre como funciona la dimensión tiempo.

Â

En el siguiente paso del asistente tenemos que seleccionar en que objeto del Data Source View nos basamos para crear la dimensión, adicionalmente hay que decir cual es la clave primaria de ese objeto (en nuestro caso es fácil, puesto que la infiere del model) y que columna contiene el descriptor de esa clave (name column). Elegiremos el campo Fecha como name column mientras mantenemos FechaKey como la clave primaria de esta dimensión.

En el siguiente paso del asistente es cuando realmente tenemos que definir que estamos hablando de una dimensión de tipo tiempo. Esto cambia con respecto a 2005, en el que había un wizard que nos preguntaba directamente cual era el campo que contenía el dato para mes, semana, dia, trimestre, etc.. En el asistente aparece un campo para definir el tipo de atributo, y es ahí donde concretamos cual es la naturaleza de cada uno de los campos,  por ejemplo, en la siguiente figura podemos ver como hemos especificado para Fecha Key que se trata de un atributo de tipo date, es decir, es la fecha propiamente dicha. También aprovecharemos este paso para ajustar los nombres que no acaben de gustarnos, (por ejemplo quitaré Fecha Key y lo traduciré por fecha.

Una vez que hemos elegido todos los atributos podemos continuar con el asistente, en la imagen que teneis a continuación podeis ver como he hecho los siguiente cambios:

  • He renombrado Fecha Key por fecha y Mes Key por mes
  • He especificado que el tipo de atributo es Date para la fecha
  • Year para el año
  • Month para el mes
  • Week para la semana
  • Day Of year para el dia del año
  • Day of Month para el dia del mes
  • Day of Week para el dia de la semana

Despues de esto simplemente se termina el asistente en el que nos dice que va  crear la dimensión tiempo como puede verse a continuación.

Esta dimensión tiempo, ya funcionaría, pero no es aún ni demasiado navegable (no tiene jerarquías) ni mucho menos optima, porque las relaciones entre atributos tampoco están especificadas. Esto si es un cambio importante en SQL Server 2008, la relación entre atributos cuenta ahora con una pestaña específica, que lo hace más visual. El estado inicial de estas relaciones entre atributos es el que puede verse en la figura a continuación.

Sin embargo, debemos especificar las relaciones reales de dependencia, ya que esas relaciones ayudarán mucho al rendimiento, debido a que con estas relaciones establecidas, SQL Server Analisys Services puede inferir, que el resultado de un mes, es el resultado de sumar los dias (para operaciones aditivas). mientras que el resultado del año es el resultado de sumar los meses. Si estas relaciones no son especificadas, esas conclusiones no pueden establecerse y por tanto se hace un uso suboptimo de los datos. En el grafico siguiente puede verse como establecemos estas relaciones de dependencia de forma adecuada.

Una parte importante, en la que muchas veces no nos fijamos es en el color de las flechitas del apartado Attibute Relasionships, el color más gris indica que la relación que existe entre esos atributos es una relación flexible, es decir que puede cambiar con el tiempo, por ejemplo en el caso del jefe del que depende una persona, es claro que puede cambiar con el tiempo, aunque sea una relación clara entre los atributos, sin embargo, en nuestro caso,  la relación Fecha->Mes y la Relación Mes-Año, están especificada como relaciones rígidas que quiere decir que el mes 2009-01 siempre será del año 2009 y eso no va a cambiar (cosa que es bastante obvia).

Una vez que tenemos establecidas las relaciones solo nos falta añadirle a la dimensión las jerarquias que nos sirvan para especificar el criterio por el que queremos que se navegue nuestra dimensión. Para ello simplemente arrastraré los atributos hasta el apartado de jerarquías. Adicionalmente voy a ocultar el atributo año, para no confundir a los usuarios, si lo dejo podrán llegar al año desde la jerarquia y desde el atributo, y en mi experiencia eso lia bastante a los usuarios. En la imagen siguiente podeis ver como quedan mis jerarquías.

Podeis observar que no tengo ningún warning ni ninguna flechita azul, esto es simplemente porque he seguido todos los patrones de buen diseño que SQL Server 2008 Analisys Services tiene especificados para una dimensión como esta. Ahora simplemente vamos a ver un ejemplo de como navegarla, lo teneis en el siguiente gráfico.

Por último, aunque esta serie de dos artículos acaba, en posteriores post, intentaré hablar de como localizar esta dimensión, especificando que para usuarios en inglés el nombre le aparezca en inglés, mientras que para usuarios en castellano los nombres aparezcan en castellano, esto es January para los Ingleses, Enero para los hispanos.
Esto será en otro post.
Saludos Cordiales

Mi charla sobre Analisys Services 2008 en el Codecamp de tarragona

Posted by Miguel Egea | Posted in Analisys Services | Posted on 18-01-2010

4

Me parece increible que yo diese esta charla y no saber que estaba grabada y publicada, gracias a mi amgigo Salvador Ramos y a un portal de bussiness intelligence me he enterado que estaba publicado. Yo no se dar una charla serio, los que me conoceis ya sabeis como soy, para los demás pues bueno, ya podeis verme y oirme.