No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Usando rank y percent rank

29/34
Recursos

Aportes 23

Preguntas 3

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

Si quisi茅ramos usar WHERE para especificar que solo queremos los lugares menores o iguales a 10, deber铆amos convertir la consulta como una subconsulta, de esta forma podremos usar lugar dentro del WHERE.

De esta forma:

SELECT *
FROM (
	SELECT
		peliculas.pelicula_id AS id,
		peliculas.titulo,
		COUNT(*) AS numero_rentas,
		DENSE_RANK() OVER(
			ORDER BY COUNT(*) DESC
		) AS lugar
	FROM rentas
		INNER JOIN inventarios ON rentas.inventario_id = inventarios.inventario_id
		INNER JOIN peliculas ON inventarios.pelicula_id = peliculas.pelicula_id
	GROUP BY peliculas.pelicula_id
	ORDER BY numero_rentas DESC
) AS top_10
WHERE lugar <= 10;

que lindas las window function! pensar que antes sacaba los datos de SQL y tenia que pasarlo a un excel para sacar porcentajes o los ranking 馃槮

DENSE_RANK: Rango por posici贸n en la tabla.

Using alias for less verbose

SELECT 
	p.pelicula_id AS id,
	p.titulo,
	COUNT(*) AS numero_rentas,
	DENSE_RANK() OVER (ORDER BY COUNT(*) DESC) AS lugar
FROM rentas AS r
JOIN inventarios AS i
ON   r.inventario_id = i.inventario_id
JOIN peliculas AS p
ON   i.pelicula_id = p.pelicula_id
GROUP BY p.pelicula_id
ORDER BY numero_rentas DESC;

PERCENT_RANK
Posicion porcentual de cada registro en la agrupacion

DENSE_RANK
Posicion por lugares de cada registro en la agrupacion

SELECT 
	peliculas.pelicula_id AS id,
	peliculas.titulo,
	COUNT(*) AS numero_rentas,
	ROW_NUMBER () OVER (
		ORDER BY COUNT(*) DESC
	) AS lugar
FROM rentas
	INNER JOIN inventarios ON rentas.inventario_id = inventarios.inventario_id
	INNER JOIN peliculas ON inventarios.pelicula_id = peliculas.pelicula_id
GROUP BY peliculas.pelicula_id
ORDER BY numero_rentas DESC
LIMIT 10;

SELECT 
	peliculas.pelicula_id AS id,
	peliculas.titulo,
	COUNT(*) AS numero_rentas,
	PERCENT_RANK() OVER (
		ORDER BY COUNT(*) DESC
	) AS lugar
FROM rentas
	INNER JOIN inventarios ON rentas.inventario_id = inventarios.inventario_id
	INNER JOIN peliculas ON inventarios.pelicula_id = peliculas.pelicula_id
GROUP BY peliculas.pelicula_id
ORDER BY numero_rentas DESC;


SELECT 
	peliculas.pelicula_id AS id,
	peliculas.titulo,
	COUNT(*) AS numero_rentas,
	PERCENT_RANK() OVER (
		ORDER BY COUNT(*) ASC
	) AS lugar
FROM rentas
	INNER JOIN inventarios ON rentas.inventario_id = inventarios.inventario_id
	INNER JOIN peliculas ON inventarios.pelicula_id = peliculas.pelicula_id
GROUP BY peliculas.pelicula_id
ORDER BY numero_rentas DESC;

SELECT 
	peliculas.pelicula_id AS id,
	peliculas.titulo,
	COUNT(*) AS numero_rentas,
	DENSE_RANK() OVER (
		ORDER BY COUNT(*) DESC
	) AS lugar
FROM rentas
	INNER JOIN inventarios ON rentas.inventario_id = inventarios.inventario_id
	INNER JOIN peliculas ON inventarios.pelicula_id = peliculas.pelicula_id
GROUP BY peliculas.pelicula_id
ORDER BY numero_rentas DESC;

percentila鈥

Me gusto mucho lo del DENSE_RANK, es muy util para sacar los datos directamente de SQL sin tener que convertirlos con otros programas.

SELECT
	peliculas.pelicula_id AS id,
	peliculas.titulo,
	COUNT(*) AS numero_rentas,
	DENSE_RANK () OVER (
		ORDER BY COUNT(*) DESC
	) AS percentil
FROM rentas
	INNER JOIN inventarios ON rentas.inventario_id = inventarios.inventario_id
	INNER JOIN peliculas ON inventarios.pelicula_id = peliculas.pelicula_id
GROUP BY peliculas.pelicula_id
ORDER BY numero_rentas DESC;

29. Usando rank y percent rank

SELECT 
	peliculas.pelicula_id AS id,
	peliculas.titulo,
	COUNT(*) AS numero_rentas,
	DENSE_RANK () OVER (
		ORDER BY COUNT(*) DESC
	) AS lugar
FROM rentas
	INNER JOIN inventarios ON rentas.inventario_id = inventarios.inventario_id
	INNER JOIN peliculas ON inventarios.pelicula_id = peliculas.pelicula_id
GROUP BY peliculas.pelicula_id
ORDER BY numero_rentas DESC
;

Excelente explicaci贸n y ejemplo al grano, ahorra tiempo.
Lo otro para reducir el c贸digo podemos remplazar el nombre de la tabla por una letra, eso hacer ver mas limpio el c贸digo

Algo mas sencillo

clasificar las pel铆culas en funci贸n de alg煤n criterio y calcular el percentil de alguna m茅trica.

SELECT
    titulo,
    precio_renta,
    RANK() OVER (ORDER BY precio_renta) AS ranking,
    PERCENT_RANK() OVER (ORDER BY precio_renta) AS percentil
FROM
    public.peliculas;

Utilizamos RANK para asignar un rango a cada pel铆cula basado en el precio de renta, y PERCENT_RANK para calcular el percentil de cada pel铆cula en funci贸n de ese mismo criterio.

SELECT 
	COUNT(*)			AS "Cantidad Rentas", 
	peliculas.titulo	AS "T铆tulo",
	DENSE_RANK()   OVER (ORDER BY COUNT(*) DESC),
	RANK() 		   OVER (ORDER BY COUNT(*) DESC),
	PERCENT_RANK() OVER (ORDER BY COUNT(*) DESC),
	ROW_NUMBER()   OVER (ORDER BY COUNT(*) DESC)

FROM rentas
	JOIN inventarios USING(inventario_id)
	JOIN peliculas   USING(pelicula_id)

GROUP BY "T铆tulo"
ORDER BY "Cantidad Rentas" DESC
LIMIT 10;

gracias por las aclaraciones

Windows functions, ejemplos de usos

驴Se han dado cuenta de que las pel铆culas del listado no existen realmente?

Inspirado en el ejemplo de uno de los compa帽eros de aqu铆, hice una peque帽a modificaci贸n que me parece de lo m谩s l贸gica, aqu铆 la tienen:

-- 'TOP TEN' usando WHERE y 'lugar' para los 10 primeros puestos.
SELECT *
FROM (
    SELECT
        peliculas.pelicula_id AS id,
        peliculas.titulo,
        COUNT(*) AS numero_rentas,
        DENSE_RANK() OVER (ORDER BY COUNT(*) DESC) AS lugar
    FROM rentas
        INNER JOIN inventarios ON rentas.inventario_id = inventarios.inventario_id
        INNER JOIN peliculas ON inventarios.pelicula_id = peliculas.pelicula_id
    GROUP BY peliculas.pelicula_id
    ORDER BY lugar ASC
) AS top_10 -- Es imprescindible tener un alias por ser una subconsulta.
WHERE lugar < 11;

Adem谩s, no me gusta ponerles alias de un s贸lo car谩cter a las tablas, puede que se 鈥榚scriba鈥 menos, pero aumenta mucho la atenci贸n que hay que poner al leer el c贸digo, me explico, hay que tener en cuenta constantemente que 鈥榚sa letra鈥 es la tabla 鈥榝ulana鈥, y la otra 鈥榤engana鈥, s铆 se pone el nombre completo, es innecesario hacer 鈥榗onversiones鈥 mentales para tal menester.

Entendido y muy potente

Muy util!!!

Super !! muy Claro鈥

Excelente,

interesante