BISM, Business Intelligence, DAX, PowerPivot, SQL Server, SQL Server 2012, Tabular Model

Obtención de N filas con TOPN. Profundizando en el uso de DAX como lenguaje de consulta (5)

La función TOPN devuelve un subconjunto de una cantidad determinada de las primeras filas pertenecientes a una tabla, en base a una expresión utilizada para ordenar dicha tabla.

Como primer parámetro pasaremos el número de filas a recuperar; en segundo lugar indicaremos la tabla de la que se obtendrán las filas; el tercer parámetro corresponderá a la expresión que realizará la ordenación de las filas; y opcionalmente, en el cuarto parámetro, pasaremos un número (0 ó 1) indicativo del sentido (ascendente o descendente) en que se realizará la ordenación especificada en el tercer parámetro.

Supongamos que de la tabla DimProduct queremos averiguar las siete marcas de productos (columna BrandName) que han generado más ventas (tabla FactSales, columna SalesAmount). Comenzaremos nuestro análisis del problema desde el motor relacional, ejecutando la siguiente consulta SQL, que nos devuelve todas las marcas de producto con sus totales de venta correspondientes.


WITH tblMarcas AS
(
	SELECT DP.BrandName,
	SUM(FS.SalesAmount) AS VentasMarca
	FROM FactSales AS FS, DimProduct AS DP
	WHERE FS.ProductKey = DP.ProductKey
	GROUP BY DP.BrandName
)
SELECT BrandName, FORMAT(VentasMarca, 'C', 'es-es') AS Ventas
FROM tblMarcas
ORDER BY VentasMarca DESC

ProfundizandoUsoDAXComoLenguajeConsulta_20

 

Para obtener aquí las siete marcas con más ventas, simplemente añadiremos la partícula TOP junto a la cantidad de filas que necesitamos obtener.


WITH tblMarcas AS
(
	SELECT DP.BrandName,
	SUM(FS.SalesAmount) AS VentasMarca
	FROM FactSales AS FS, DimProduct AS DP
	WHERE FS.ProductKey = DP.ProductKey
	GROUP BY DP.BrandName
)
SELECT TOP 7 BrandName, FORMAT(VentasMarca, 'C', 'es-es') AS Ventas
FROM tblMarcas
ORDER BY VentasMarca DESC

Vamos a realizar un primer intento para conseguir este mismo resultado en DAX, utilizando la función TOPN en la siguiente consulta.


EVALUATE
TOPN(
	7,
	VALUES('DimProduct'[BrandName]),
	SUM('FactSales'[SalesAmount]),
	0
)

Los resultados, no obstante, no serán nada satisfactorios porque, por un lado, obtenemos todos los nombres de marcas de producto, y por otro, no aparecen los importes de ventas por marca. Observando detenidamente la documentación de la función veremos que esto es completamente lógico, ya que TOPN devuelve las filas de la tabla pasada en el segundo parámetro según el resultado de aplicar la expresión del tercero.

Como primer paso para acercarnos a la solución añadiremos a la consulta una medida calculada, que será la encargada de sumar la columna SalesAmount; esta medida la emplearemos a continuación como tercer parámetro de TOPN.


DEFINE
MEASURE DimProduct[VentasPorMarca] = SUM(FactSales[SalesAmount])

EVALUATE
TOPN(
	7,
	VALUES('DimProduct'[BrandName]),
	DimProduct[VentasPorMarca],
	0
)

ProfundizandoUsoDAXComoLenguajeConsulta_21

 

Con esto casi hemos cumplido con nuestro objetivo, tan sólo nos falta visualizar la columna con los importes de ventas, para lo cual recurriremos a la función ADDCOLUMNS, a la que pasaremos como parámetro la función TOPN y la expresión con la columna calculada que realiza la suma de las ventas.


DEFINE
MEASURE 'DimProduct'[VentasPorMarca] = SUM('FactSales' [SalesAmount])

EVALUATE
ADDCOLUMNS(
	TOPN(
		7,
		VALUES('DimProduct'[BrandName]),
		'DimProduct'[VentasPorMarca],
		0
	),
	"Ventas por nombre marca", FORMAT('DimProduct'[VentasPorMarca], "Currency")
)
ORDER BY 'DimProduct'[VentasPorMarca] DESC

ProfundizandoUsoDAXComoLenguajeConsulta_22

 

Aunque podamos estar acostumbrados al uso de la partícula TOP en Transact-SQL, en el contexto de las consultas y expresiones con DAX es probable que el empleo de TOPN no resulte tan intuitivo como a priori cabría esperar. En este enlace se proporciona una explicación más detallada sobre dicha función, y en este post se muestra un interesante caso de uso.

2 Comentarios

  1. kiquenet

    Muy buena serie, Luismi !

  2. lmblanco

    Hola Enrique

    Muchas gracias por tu opinión y celebro que te estén gustando los post sobre este tema. En próximos días iré añadiendo alguno más 🙂

    Un saludo,
    Luismi

Deja un comentario

Tema creado por Anders Norén