No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso Práctico de SQL

Curso Práctico de SQL

Israel Vázquez Morales

Israel Vázquez Morales

Selectores de rango

16/29
Recursos

Aportes 136

Preguntas 15

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Los tipos de rango que vienen en PostgreSQL son:

  • int4range: Que trae un rango de enteros.

  • int8range: Es un rango de enteros grandes.

  • numrange: Es un rango numérico.

  • tsrange: Es un rango del tipo timestamp pero sin la zona horaria.

  • tstzrange: Es un rango del tipo timestamp con la zona horaria

  • daterange: Es un rango del tipo fecha.

    Esos son los que podemos usar como selectores de rango dentro de PostgreSQL si les interesa conocer más Acá

Solucion del reto

SELECT INT4RANGE(MIN(tutor_id), MAX(tutor_id)) * INT4RANGE(MIN(carrera_id), MAX(carrera_id))
    FROM platzi.alumnos;

Como cuando crees que dominas Postgres y aparece esto. 😮

En SQL Server

-- CREAR UN RANGO DE VALORES [9; 11]
SELECT TOP 11
	9 + ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY A.name) AS 'Range'
FROM syscolumns A, syscolumns B


-- UNION DE 2 RANGOS
(
	SELECT TOP 9 -- [11; 19]
		10 + ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY A.name) AS 'Range'
	FROM syscolumns A, syscolumns B
)
UNION
(
	SELECT TOP 11 -- [15; 25]
	14 + ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY A.name) AS 'Range'
    FROM syscolumns A, syscolumns B
)

-- INTERSECCION DE 2 RANGOS
(
	SELECT TOP 9 -- [11; 19]
		10 + ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY A.name) AS 'Range'
	FROM syscolumns A, syscolumns B
)
INTERSECT
(
	SELECT TOP 11 -- [15; 25]
	14 + ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY A.name) AS 'Range'
    FROM syscolumns A, syscolumns B
)


-- METODO 3
-- RANGO CON UNA SUBCONSULTA
USE [platzi]
SELECT *
FROM platzi.alumnos
WHERE tutor_id IN
(
	SELECT TOP 11
	9 + ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY A.name) AS 'Range'
	FROM syscolumns A, syscolumns B
)
GO 


/*
INTERSECCION ENTRE CARRERA_ID Y TUTOR_ID
*/

SELECT carrera_id AS interseccion
FROM 
(
	(
		SELECT DISTINCT carrera_id
		FROM platzi.alumnos
	)
	INTERSECT
	(
		SELECT DISTINCT tutor_id
		FROM platzi.alumnos
	)
) AS interseccion_ids


Reto:

<code> 
SELECT *
FROM platzi.alumnos
WHERE tutor_id = carrera_id;

Mi respuesta :

‘=>’ Significa ‘devuelve’ en este apunte

‘&&’ si se solapan estos dos rangos

(11.1,22.2) && (20.0,30.0) => TRUE
(11.1,19.9) && (20.0,30.0) => FALSE

* Para seleccionar los elementos de la interseccion entre los dos rangos. SI no hay, marca error

SELECT int4ramge(10,20) * int4range(15,25) =>[15,20)

@> si el rango se encuentra en el grupo

SELECT *
FROM platzi.alumnos
WHERE int4range(10,20) @> tutor_id

Selectores de rango
Son especialmente útiles para utilizar en el WHERE statement.

SELECT int4range(1,20) @> 3;

Esta consulta trae un entero pequeño y pregunta si el rango contiene al numero 3

SELECT numrange(11,20) && numrange(20.0, 30.0);

Esta consulta trae un resultado booleano, ya que los && consultan entre los dos rangos de números de alta precisión si existen valores solapados entre ambos

SELECT LOWER int8range(15,25);

Simplemente trae el menor número del rango. Funciona igual con UPPER

SELECT int4range(10,20) * int4range(15,25);

Esta consulta trae el rango numérico que comparten ambos rangos

SELECT ISEMPTY(numrange(1,5));

Booleano que detecta si el rango esta vacío

SACAR EL RANGO QUE HAY ENTRE TUTOR_ID Y CARRERA_ID

SELECT int4range(min(tutor_id), max(tutor_id)) * int4range(min(carrera_id), max(carrera_id))
FROM platzi.alumnos;

SACAR LOS DATOS QUE PERTENECEN AL RANGO ENTRE TUTOR_ID Y CARRERA_ID

SELECT *
FROM platzi.alumnos
WHERE(
SELECT int4range(MIN(tutor_id), MAX(tutor_id)) * int4range(MIN(carrera_id),MAX(carrera_id))
FROM platzi.alumnos
) @> tutor_id
AND
(
SELECT int4range(MIN(tutor_id), MAX(tutor_id)) * int4range(MIN(carrera_id),MAX(carrera_id))
FROM platzi.alumnos
) @> carrera_id;

Mi solución

SELECT 
	numrange(min_carrera, max_carrera) * numrange(min_tutor, max_tutor)
FROM (
	SELECT 
		MIN(carrera_id) as min_carrera,
		MAX(carrera_id) as max_carrera,
		MIN(tutor_id) as min_tutor,
		MAX(tutor_id) as max_tutor
	FROM alumnos
) AS rangos

RESPUESTA DEL RETO en MySQL

SELECT a.tutor_id,b.carrera_id
FROM alumnos as a
inner JOIN alumnos as b
ON a.tutor_id = b.carrera_id
group by a.tutor_id
order by a.tutor_id

SELECT *
FROM platzi.alumnos
WHERE int4range(10,20) @> tutor_id 
	AND int4range(10,20) @> carrera_id```

Hola, entendí que la tarea era traer todos los campos en común, así que este fue mi Query:

NOTA: Antes de realizar esto, verificar los rangos de cada una de las columnas, ya que pueden caer en el rango más amplio (en este caso el de “carrera_id” que es de 1 a 50) y traer lo que este contenga respecto al rango a comparar, en el caso de “tutor_id” que es de 1 a 30, entonces nos seguiría trayendo todos los datos de la tabla sin más.

<SELECT *
FROM PLATZI.ALUMNOS
WHERE INT4RANGE((SELECT MIN(TUTOR_ID) FROM PLATZI.ALUMNOS), 
				(SELECT MAX(TUTOR_ID) FROM PLATZI.ALUMNOS)) 
@> CARRERA_ID;

Mi solución al Reto de la clase.

En este codigo se seleccionan todas las filas que contengan id en común entre carrera y tutor.

SELECT *
FROM platzi.alumnos
WHERE int4range((SELECT MIN(tutor_id) FROM platzi.alumnos), (SELECT MAX(tutor_id) FROM platzi.alumnos)) @> carrera_id;

Solución al reto de la clase anterior

WITH cte AS (
	SELECT id,
	ROW_NUMBER() OVER (
		PARTITION BY
			nombre,
			apellido,
			email,
			colegiatura,
			fecha_incorporacion,
			carrera_id,
			tutor_id
		ORDER BY id ASC
	) AS row
	FROM platzi.alumnos
)
DELETE FROM platzi.alumnos
USING cte
WHERE platzi.alumnos.id = cte.id
AND cte.row > 1;
SELECT ISEMPTY (numrange(1,5)) --FALSE
SELECT ISEMPTY (numrange(1,1)) --TRUE

LOWER= nos devuleve el valor mas bajo de un rango

Use este query y se me borro toda la base de datos, como hago para restaurarla al punto anterior al query.


DELETE FROM platzi.alumnos 
WHERE id IN 
	(SELECT id FROM(
		SELECT id FROM (
			SELECT ROW_NUMBER() OVER( PARTITION BY
				nombre, apellido,
				email, colegiatura,
				fecha_incorporacion, carrera_id,
				tutor_id ORDER BY id ASC) AS row
		FROM platzi.alumnos) AS duplicados 
		WHERE duplicados.row >1) AS duplicados_id);```

Listo!

SELECT 

int4range(
(SELECT MIN (Carrera_id)), (SELECT MAX (Carrera_id))) 
* 
int4range(
(SELECT MIN (tutor_id)), (SELECT MAX (tutor_id)))

FROM platzi.alumnos;
SELECT int4range((SELECT min(carrera_id) FROM platzi.alumnos),
				 (SELECT max(carrera_id) FROM platzi.alumnos)) *
	int4range((SELECT min(tutor_id) FROM platzi.alumnos),
			  (SELECT max(tutor_id) FROM platzi.alumnos));
Mi solucion del reto de la clase pasada: ```js DELETE FROM platzi.alumnos WHERE id = ( SELECT id FROM ( SELECT * FROM ( SELECT id, ROW_NUMBER() OVER( PARTITION BY nombre, apellido, email, colegiatura, fecha_incorporacion, carrera_id, tutor_id ORDER BY id ASC ) AS row--, --* FROM platzi.alumnos ) AS duplicados WHERE duplicados.row > 1 ) ); ```

Así mandé llamar los registros que el id de la carrera y del tutor se encuentre dentro del rango de intersección

<code> 
SELECT * FROM platzi.alumnos

WHERE

int4range (
	(SELECT MIN(carrera_id) FROM platzi.alumnos),
	(SELECT MAX (carrera_id) FROM platzi.alumnos)
)   @> tutor_id

or

int4range (
	(SELECT MIN(tutor_id) FROM platzi.alumnos),
	(SELECT MAX (tutor_id) FROM platzi.alumnos)
)   @> carrera_id
	;

SELECT int4range(10,20) * int4range(15,25) --[15,20)
SELECT int4range(10,30) * int4range(15,25) --[15,25)
SELECT int4range(15,25) * int4range(30,40) --ERROR
SELECT int4range(30,40) * int4range(15,25) --empty

Rango [15, 20)

  • Incluye: 15
  • Excluye: 20
SELECT numrange(11.5 , 19.9) && numrange(20.0 , 30.0) --FALSE
SELECT numrange(11.5 , 20.0) && numrange(20.0 , 30.0) --FALSE
SELECT numrange(11.5 , 20.1) && numrange(20.0 , 30.0) --TRUE 

smallint

  • 2 bytes
  • -32768 to +32767

integer

  • 4 bytes
  • -2147483648 to +2147483647
-- Relación de rangos entre tutores y carreras
SELECT  int4range(MIN(tutor_id), MAX(tutor_id)) *  int4range(MIN(carrera_id), MAX(carrera_id))
FROM platzi.alumnos;

Solución al reto:

SELECT int8range(MIN(carrera_id), MAX(carrera_id))* 
		int8range(MIN(tutor_id), MAX(tutor_id))
FROM platzi.alumnos;

Mi propuesta

SELECT int4range(min(tutor_id), max(tutor_id)) * int4range("min"(carrera_id), "max"(carrera_id))
FROM platzi.alumnos;

No enterndí el uso de

SELECT numrange(11.1, 19.9) && numrange(20.0, 30.0);

A qué se refiere con solapar?, unos número que se solapan qué es?

chequeate esta easy kill:

SELECT int4range(minimo_tutor,maximo_tutor) * int4range(minimo_carrera,maximo_carrera) AS interseccion
FROM (
		SELECT MIN(tutor_id) AS minimo_tutor, MAX(tutor_id) AS maximo_tutor, MIN(carrera_id) AS minimo_carrera, MAX(carrera_id) AS maximo_carrera
		FROM platzi.alumnos
) AS subconsulta;

Reto: extraer todos lo valores que hallan en comun entre los id de tutores y los id de carreras

SELECT *
FROM (
	SELECT 
	ROW_NUMBER() OVER() AS row_id, *
	FROM platzi.alumnos
) AS range_alumnos
WHERE carrera_id BETWEEN tutor_id AND tutor_id
	OR tutor_id BETWEEN carrera_id AND carrera_id;
SELECT id, carrera_id, tutor_id
from platzi.alumnos
where carrera_id = tutor_id;
SELECT (
	       int4range(MIN (carrera_id), MAX (carrera_id)) *
         int4range(MIN (tutor_id),   MAX (tutor_id))
        ) AS interseccion 
FROM platzi.alumnos;

Mi solución al reto:

Dado que hay 50 carreras y todos los tutores entran en alguna carrera, el mejor ejemplo sería traerme las carreras que se encuentren en los ids de Tutores, es decir, hasta 30.

SELECT *
FROM platzi.alumnos
WHERE carrera_id IN (
	SELECT DISTINCT tutor_id 
	FROM platzi.alumnos )
ORDER BY tutor_id, carrera_id;

DELETE FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM platzi.alumnos
GROUP BY id
HAVING COUNT(*) > 1
)

así borré el duplicado

El reto:

SELECT int4range(MIN(tutor_id), MAX(tutor_id)) * int4range(MIN(carrera_id), MAX(carrera_id))
FROM platzi.alumnos;

–Otra forma de hacer el borrado del campo repetido
DELETE
FROM platzi.alumnos
WHERE id NOT IN (
SELECT id FROM (
SELECT id,
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
) AS row
FROM platzi.alumnos
) AS duplicados
WHERE duplicados.row > 1
);

SELECT int4range(min(carrera_id),max(carrera_id)) * int4range(min(tutor_id),max(tutor_id))
FROM platzi.alumnos;
SELECT * 
FROM platzi.alumnos
WHERE int4range (10, 50) @> tutor_id;

SELECT * 
FROM platzi.alumnos
WHERE int4range (10, 50) @> carrera_id; 
SELECT *
FROM platzi.alumnos
WHERE (
	SELECT int4range(MIN(carrera_id),MAX(carrera_id)) * int4range(MIN(tutor_id),MAX(tutor_id))
	FROM platzi.alumnos) @> tutor_id 
	AND (
	SELECT int4range(MIN(carrera_id),MAX(carrera_id)) * int4range(MIN(tutor_id),MAX(tutor_id))
	FROM platzi.alumnos) @> carrera_id 
	;

Mi respuesta al reto pero utilizando Max y Min

select alu from (
	select 
	int4range(min(a.tutor_id), max(a.tutor_id))
	* int4range(min(a.carrera_id), max(a.carrera_id)) as interseccion
	from alumnos a) as resumen, 
	alumnos alu
	where 
		interseccion @> alu.tutor_id
		and interseccion @> alu.carrera_id
	order by alu.carrera_id, alu.tutor_id;
SELECT int4range(MIN(tutor_id), MAX(tutor_id)) * int4range(MIN(akumno_id), MAX(alumno_id))
FROM platzi.alumnos

En el delete no tuve mucho que poner ya que solo existen 2 registro de haber mas, considero que en el where pondria mas campos para que se tomen en cuenta

delete from platzi.alumnos where id = 1001

Reto

SELECT numrange(min(tutor_id), max(tutor_id)) * numrange(min(carrera_id), max(carrera_id))
FROM platzi.alumnos

Reto Anterior

DELETE
FROM platzi.alumnos
WHERE id IN (
SELECT id
FROM (
SELECT id,
ROW_NUMBER () OVER (
PARTITION BY
nombre, 
apellido,
email,
colegiatura, 
fecha_incorporacion,
carrera_id,
tutor_id
	ORDER BY id ASC
	)AS row
FROM platzi.alumnos
	)AS duplicados
	WHERE duplicados.row > 1);
	

RETO

SELECT int4range(MIN(tutor_id),MAX(tutor_id)) *
    int4range(MIN(carrera_id),MAX(carrera_id))
FROM platzi.alumnos
<code> 

Esta fue mi solución al reto:

SELECT numrange(
	(SELECT MIN(tutor_id) FROM platzi.alumnos),
	(SELECT MAX(tutor_id) FROM platzi.alumnos)
) * numrange(
	(SELECT MIN(carrera_id) FROM platzi.alumnos),
	(SELECT MAX(carrera_id) FROM platzi.alumnos)
);
--Solución para obtener  la intersección o elementos en común entre tutor_id y carrera_id

--Forma 1 :
SELECT numrange((SELECT MIN(tutor_id)
				FROM platzi.alumnos),
				(SELECT MAX(tutor_id)
					FROM platzi.alumnos)) * 
	   numrange((SELECT MIN(carrera_id)
					FROM platzi.alumnos),
				(SELECT MAX(carrera_id)
					FROM platzi.alumnos));

--Forma 2: 
SELECT int4range(( SELECT MIN(tutor_id)
					FROM platzi.alumnos), 
				(SELECT MAX(tutor_id)
					FROM platzi.alumnos)) *
	   int4range(( SELECT MIN(carrera_id)
					FROM platzi.alumnos), 
				(SELECT MAX(carrera_id)
					FROM platzi.alumnos));

En SQL Server:
– Borrado de arreglo de ID por partición por todos los campos –
DELETE FROM alumnos
WHERE id IN
(
SELECT id
FROM (
SELECT id,
ROW_NUMBER() OVER(
PARTITION BY
nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id asc
) AS row
FROM alumnos
) duplicados
WHERE duplicados.row > 1
);

/**

  • Rangos y solapes
    */

– Ejemplos iniciales –
SELECT *
FROM alumnos
WHERE tutor_id IN (11,12,13,14,15,16,17,18,19,20);

SELECT *
FROM alumnos
WHERE tutor_id >= 1
AND tutor_id <= 10;

SELECT *
FROM alumnos
WHERE tutor_id BETWEEN 1 AND 10;

– ¿En rango? –
SELECT 3
from alumnos
where tutor_id BETWEEN 10 AND 20;

– Filtrar alumnos cuyo tutor_id esté entre 1 y 10 –
SELECT *
FROM alumnos
WHERE tutor_id >= 10 AND tutor_id <= 20

RETO RESUELTO: Obtener el rango de IDs para tutores y el rango de los IDs de carreras .

SELECT int4range(MIN(tutor_id),MAX(tutor_id),'[]') AS rango_tutores,
	   int4range(MIN(carrera_id),MAX(carrera_id),'[]') AS rango_carreras
	   FROM platzi.alumnos

El rango de valores comunes para los IDs de tutores y de carreras

 int4range(MIN(tutor_id),MAX(tutor_id),'[]') AS rango_tutores *
 int4range(MIN(carrera_id),MAX(carrera_id),'[]') AS rango_carreras
-- Devuelve el rango de overlap que es [1,31)

Mostrar solo los alumnos en las que los IDs de tutor y de carrera estén dentro de este rango común

SELECT *
FROM platzi.alumnos
WHERE (SELECT 
	   int4range(MIN(tutor_id),MAX(tutor_id),'[]') *
	   int4range(MIN(carrera_id),MAX(carrera_id),'[]')
	   FROM platzi.alumnos  
	  ) @> carrera_id
;

Como podemos apreciar solo hay IDs de tutores y carreras entre [1,31) es decir del 1 al 30 (6043registros cumplen esa restricción)

Aclaración:

El int4range(a, b) genera el rango de valores enteros [a, b) es decir, incluye el valor inferior, pero excluye al valor superior.
Por ejemplo si hacemos las consultas:

SELECT int4range(10, 20);          -- Rango resultante es [10,20)    
SELECT int4range(10, 20) @> 10;    -- Devuelve true
SELECT int4range(10, 20) @> 20;    -- Devuelve false

Takeaway: Igual que la notación matemática de rangos, corchete incluye y paréntesis excluye a un valor.

Mi solución al reto:

 SELECT *
 FROM (
 	SELECT int4range(MIN(tutor_id),MAX(tutor_id)) * int4range(MIN(carrera_id),MAX(carrera_id))
 	FROM platzi.alumnos
 ) AS rangos_alumnos;

Lo que entendí es mostrar que valores de carrera_id están en el rango de valores de tutor_id o viceversa, basado en eso, esta es mi solución:

select distinct carrera_id from platzi.alumnos
where carrera_id in (select distinct tutor_id from platzi.alumnos);
DELETE FROM platzi.alumnos
	WHERE id IN(
		SELECT id
		FROM platzi.alumnos AS ou 
		WHERE ( 
			SELECT COUNT(*)
			FROM platzi.alumnos AS inr
			WHERE ou.email = inr.email
			) > 1
		OFFSET 1
		)

Mi solución al reto:

SELECT * FROM platzi.alumnos
WHERE tutor_id = carrera_id
ORDER BY tutor_id ASC;

Aunque no lo trae como rango si me trae los valores en común

SELECT DISTINCT carrera_id
FROM platzi.alumnos
WHERE carrera_id IN (
	SELECT tutor_id FROM platzi.alumnos
) ORDER BY carrera_id ASC;

segun mi logica esta es la solucion planteada desde un punto diferente

SELECT *
FROM platzi.alumnos
where tutor_id in (SELECT platzi.alumnos.tutor_id
				 from platzi.alumnos
				 GROUP BY(tutor_id)) and carrera_id in(SELECT platzi.alumnos.tutor_id
				 from platzi.alumnos
				 GROUP BY(tutor_id))

comparto mi solucion para encontrar el rango

select numrange(min(tutor_id), max (tutor_id)) * numrange (min(carrera_id),max (carrera_id))
from platzi.alumnos;
    

tambien realice este otro query para saber que alumnos tenian la clase con el mismo numero de tutor

SELECT id,carrera_id, tutor_id
FROM platzi.alumnos
WHERE tutor_id = carrera_id
order by tutor_id;

RETO
Seleccionar el rango de numeros de los valores que hay en común entre los id’s de tutores y carreras.


SELECT int4range(MIN(tutor_id), MAX(tutor_id)) * int4range(MIN(carrera_id), MAX(carrera_id))
FROM platzi.alumnos;

– Rangos en común entre tutores y carreras

select 
	numrange(MIN(tutor_id), MAX(tutor_id)) * numrange(MIN(carrera_id), MAX(carrera_id)) as en_comun, 
	numrange(MIN(tutor_id), MAX(tutor_id)) as rago_turores, 
	numrange(MIN(carrera_id), MAX(carrera_id)) as rango_carreras 
from 
	platzi.alumnos

Yo lo solucione de está forma

SELECT *
FROM platzi.alumnos
WHERE tutor_id IN (carrera_id);

SELECT INT4RANGE (MIN (tutor_id), MAX(tutor_id)) *
INT4RANGE (MIN (carrera_id), MAX(carrera_id))
FROM platzi_alumnos;

Con la Query SELECT *
FROM platzi.alumnos
WHERE int4range(10,20) @>tutor_id; arroja 347 registros, por el contrario con la query SELECT *
FROM platzi.alumnos
WHERE tutor_id BETWEEN 10 AND 20; arroja 383 registros, creo que esto se debe a que con la primera no tiene en cuenta los tutores id=20, con la segunda si

Muchas gracias por la clase!

Hola! comparto mi solucion del reto:

SELECT 
	int4range(MIN(carrera_id), MAX(carrera_id))
     * int4range(MIN(tutor_id), MAX(tutor_id))
FROM platzi.alumnos

Solución al reto
Rango de valores en comun entre los ID de carreras y tutor

select int4range(min(rango), max(rango))
from(
	select tutor_id as Rango
	from platzi.alumnos
	where tutor_id = carrera_id) as rangos_tabla;

Solución al reto:

SELECT int4range(MIN(carrera_id), MAX(carrera_id)) * int4range(MIN(tutor_id),MAX(tutor_id))
FROM platzi.alumnos

resultado [1,30)

Yo no recomendaría hacer un DELETE con la sentencia IN (DELETE FROM table WHERE id IN), ya que puede llegar a pasar que borramos más de una tupla.
Por lo tanto, yo aconsejaría hacer una de las siguientes dos cosas:

  • Si usas la sentencia IN, agrega el LIMIT 1
  • De otra forma, hazlo de la siguiente manera DELETE FROM table WHERE id = condition
SELECT 
numrange (MIN(tutor_id), MAX(tutor_id)) 
FROM (
	SELECT DISTINCT(tutor_id)
	FROM platzi.alumnos
	WHERE tutor_id = carrera_id
	ORDER BY tutor_id ASC
) AS rango
;

Aquí les dejo mi solución al reto:

SELECT 
int4range((SELECT MIN(carrera_id) FROM platzi.alumnos), (SELECT MAX(carrera_id) FROM platzi.alumnos)) *
int4range((SELECT MIN(tutor_id) FROM platzi.alumnos), (SELECT MAX(tutor_id) FROM platzi.alumnos));
--Modo 1:
SELECT int4range(MIN(tutor_id), MAX(tutor_id)) * int4range(MIN(carrera_id), MAX(carrera_id)) AS interseccion
FROM platzi.alumnos;

--Modo 2:
SELECT 
	numrange(min_carrera, max_carrera) * numrange(min_tutor, max_tutor) AS interseccion
FROM (
	SELECT 
		MIN(carrera_id) as min_carrera,
		MAX(carrera_id) as max_carrera,
		MIN(tutor_id) as min_tutor,
		MAX(tutor_id) as max_tutor
	FROM platzi.alumnos
) AS rangos;

Posible Respuesta:

SELECT  int4range( (SELECT MIN(carrera_id) FROM platzi.alumnos), 
(SELECT MAX(carrera_id) FROM platzi.alumnos)) * int4range(
				(SELECT MIN(tutor_id) FROM platzi.alumnos), 
(SELECT MAX(tutor_id) FROM platzi.alumnos));

Primero busque los MAX y MIN de los campos carrera_id y tutor_id con

SELECT MAX/MIN ()
FROM platzi.alumnos

Luego con el comando de calculo de intersección saco el conjunto en comun entre ambos reemplazando la querys donde van el max y min de tutor_id y carrera_id

SELECT int4range(,) * int4range(,);

Finalmente con esto armado, filtro por el conjunto obtenido
reemplazando en valor la query anterior que ya me va a arrojar un conjunto

SELECT *
FROM platzi.alumnos
WHERE int4range(,) @> tutor_id;

Resultado final:

SELECT *
FROM platzi.alumnos
WHERE int4range((SELECT int4range(
					(SELECT MIN (carrera_id)
					FROM platzi.alumnos), (
					SELECT MAX (carrera_id)
					FROM platzi.alumnos)) 
				* int4range(
					(SELECT MIN (tutor_id)
					FROM platzi.alumnos),
					(SELECT MAX (tutor_id)
					FROM platzi.alumnos)))
) @> tutor_id;

Hola, esta fue mi solucion parcial al reto:

SELECT *
FROM platzi.alumnos
WHERE alumnos.tutor_id<@(
	SELECT (int4range(MIN(tutor_id),MAX(tutor_id)) * int4range(MIN(carrera_id),MAX(carrera_id))) AS valores_comunes
	FROM platzi.alumnos
SELECT int4range(MIN(carrera_id),MAX(carrera_id), '[]') * int4range(MIN(tutor_id),MAX(tutor_id), '[]') AS intersección_ids
FROM platzi.alumnos;
--Aporte desde MySQL
SELECT a.tutor_id,b.carrera_id
FROM alumnos as a
inner JOIN alumnos as b
ON a.tutor_id = b.carrera_id
group by a.tutor_id
order by a.tutor_id;

Mi Reto:

select * 
from platzi.alumnos
where tutor_id = carrera_id;

Mi solución al reto. No creo que sea muy práctico pero jala.

SELECT *
FROM platzi.alumnos
WHERE (
	SELECT UPPER(int8range(0, tutor_id))
) = carrera_id;
SELECT 
	numrange(min_c, max_c) * numrange(min_t, max_t)
FROM (
	SELECT 
		MIN(carrera_id) as min_c,
		MAX(carrera_id) as max_c,
		MIN(tutor_id) as min_t,
		MAX(tutor_id) as max_t
	FROM alumnos
) AS rangos

Bueno así deje el query de eliminación

WITH duplicados AS (
	SELECT
		id,
		ROW_NUMBER() OVER(
			PARTITION BY
				nombre,
				apellido,
				email,
				colegiatura,
				fecha_incorporacion,
				carrera_id,
				tutor_id
			ORDER BY id ASC
		) AS row
	FROM platzi.alumnos
), duplicados_a_borrar AS (
	SELECT
		id
	FROM duplicados
	WHERE duplicados.row > 1
)

DELETE FROM platzi.alumnos
WHERE id IN ( SELECT * FROM duplicados_a_borrar	)

Aquí está mi respuesta;
En la primera consulta veo si hay intersecciones y en la segunda veo cuales son:

select int4range(min(tutor_id),max(tutor_id)) && int4range(min(carrera_id),max(carrera_id))
from platzi.alumnos

select int4range(min(tutor_id),max(tutor_id))*int4range(min(carrera_id),max(carrera_id))
from platzi.alumnos

El reto:

SELECT int4range(MIN(carrera_id),MAX(carrera_id)) * int4range(MIN(tutor_id),MAX(tutor_id))
FROM platzi.alumnos;

Desafío:

-- Reto: Interseccion o valores en comun entre dos rangos: los id de tutores y los id de carreras

-- Comparten numeros ambos rangos? 

SELECT numrange(MIN(platzi.alumnos.carrera_id), MAX(platzi.alumnos.carrera_id)) 
&& numrange(MIN(platzi.alumnos.tutor_id), MAX(platzi.alumnos.tutor_id)) AS comparten_rango
from platzi.alumnos;

-- ¿Que numeros comparten?

SELECT numrange(MIN(platzi.alumnos.carrera_id), MAX(platzi.alumnos.carrera_id)) 
* numrange(MIN(platzi.alumnos.tutor_id), MAX(platzi.alumnos.tutor_id)) AS numeros_compartidos
from platzi.alumnos;

WITH STUDENT_DATA AS
(SELECT id
FROM (
SELECT id, ROW_NUMBER() OVER(PARTITION BY nombre,
apellido,
email,
colegiatura,
fecha_incorporacion,
carrera_id,
tutor_id
ORDER BY id ASC
)AS rep_data_student
FROM platzi.alumnos
)AS dups
WHERE dups.rep_data_student > 1
)
DELETE
FROM platzi.alumnos
WHERE id IN (SELECT id
FROM STUDENT_DATA);

solución al reto del video anterior

delete from platzi.alumnos
where id in (
	select row_num
	from (
		select id, row_number() over(
			partition by nombre, apellido, email, colegiatura, carrera_id, tutor_id
			order by id asc
		) as row_num
		from platzi.alumnos
		order by id desc
	) as alumnos_with_row_num
	where row_num > 1
)

SELECT int4range(min(carrera_id),max(carrera_id)) * int4range(min(tutor_id),max(tutor_id))
FROM platzi.alumnos;

Tarea

Uso de rangos para filtrado de datos de una tabla

Evaluación de rangos vacios ISEMPTY(rango)

Interseccion de rangos [rango * rango]

UPPER y LOWER, seleccion de valores maximos y minimos dentro de un rango.

Creacion de un rango y evaluación de solapamiento (rango && rango)

Creacion de un rango con int4range y consulta de un valor dentro de ese rango

Selección de un conjunto de datos empleando IN, condicion booleana y BETWEEN

Solución de tarea leccion 15 Eliminar Duplicados

/*EJERCICIO VIDEO SELECTORES DE RANGO*/
select int4range(min(carrera_id),max(carrera_id)) * 
	   int4range(min(tutor_id),max(tutor_id))
from platzi.alumnos;

Mi aporte, no es mucho pero es trabajo honesto :

SELECT *
FROM platzi.alumnos 
WHERE (
	SELECT * 
	FROM (
		SELECT INT4RANGE((SELECT MIN(tutor_id) 
		FROM platzi.alumnos), (SELECT MAX(tutor_id) 
		FROM platzi.alumnos)) * INT4RANGE((SELECT MIN(carrera_id) 
		FROM platzi.alumnos), (SELECT MAX(carrera_id) 
		FROM platzi.alumnos)) AS RANGO
		) AS INTERSIONES  
) @> tutor_id AND (
	SELECT * 
	FROM (
		SELECT INT4RANGE((SELECT MIN(tutor_id) 
		FROM platzi.alumnos), (SELECT MAX(tutor_id) 
		FROM platzi.alumnos)) * INT4RANGE((SELECT MIN(carrera_id) 
		FROM platzi.alumnos), (SELECT MAX(carrera_id) 
		FROM platzi.alumnos)) AS RANGO
		) AS INTERSIONES  
) @> carrera_id
ORDER BY carrera_id;
	

)

RETO
¡Listo!

-- Conocer las tuplas que se encuentran --
-- en la intersección de los rangos --
-- de tutor_id y carrera_id --
SELECT *
FROM platzi.alumnos
WHERE (
	SELECT
	int4range(MIN(tutor_id), MAX(tutor_id)) * 
	int4range(MIN(carrera_id), MAX(carrera_id)) AS tcrange
	FROM platzi.alumnos
) @> tutor_id

AND (
	SELECT
	int4range(MIN(tutor_id), MAX(tutor_id)) * 
	int4range(MIN(carrera_id), MAX(carrera_id)) AS tcrange
	FROM platzi.alumnos
) @> carrera_id;

-- Saber la intersección de los rangos --
-- de tutor_id y carrera_id --
SELECT
int4range(MIN(tutor_id), MAX(tutor_id)) * 
int4range(MIN(carrera_id), MAX(carrera_id)) AS tcrange
FROM platzi.alumnos;