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

El segundo más alto

11/29
Recursos

Aportes 489

Preguntas 37

Ordenar por:

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

o inicia sesión.

Me costó un poco entender la primer consulta jaja, pero en caso de que tengan la misma duda de por qué funcionó, lo aclaro.

Dentro del subquery lo que hace es comparar dos copias de la misma columna, por ejemplo

a1.colegiatura = [2000, 4800, 1000, 5000, 3000] # Disctinct 
a2.colegiatura = [2000, 4800, 1000, 5000, 3000] # Distinct

Para cada valor, obtiene los valores que son mayores o igual a él

2000 -> 3000, 5000, 4800, 2000
4800 -> 5000, 4800
1000 -> 3000, 5000, 4800, 2000, 1000
5000 -> 5000
3000 -> 3000, 5000, 4800

Y finalmente obtiene la cuenta de ellos.

colegiatura = [2000, 4800, 1000, 5000, 3000] 
count = [4, 2, 5, 1, 3]

Esto se traduce a un ordenamiento con indexación y es por eso que elegir el 2 nos dará el segundo valor de colegiatura más alto. Este método es muy poco eficiente porque requiere de n^2 pasos (hizo 5 comparaciones por los 5 valores) mientras que un order by requiere en promedio nlogn pasos.

Mi query
SELECT * FROM platzi.alumnos OFFSET ( SELECT (COUNT(id)/2) FROM platzi.alumnos )

No estoy segura de si estoy en lo correcto, pero en el tercer Query creo que el WHERE tutor_id = 20 tiene que estar fuera del subquery, digo esto porque cuando realice el mismo Query que el tutor me traia todas las colegiaturas de 4800 pero con todos los tutores:

SELECT *
FROM platzi.alumnos AS datos_alumnos
INNER JOIN (
	SELECT DISTINCT colegiatura
	FROM platzi.alumnos
	ORDER BY colegiatura DESC
	LIMIT 1 OFFSET 1
) AS segunda_mayor_colegiatura
ON datos_alumnos.colegiatura = segunda_mayor_colegiatura.colegiatura
WHERE tutor_id = 20;

colocando el WHERE en el Query principal si aplica la condición de que sea la segunda colegiatura más alta con el tutor n° 20.

Acepto feedback en caso de estar equivocada.

SELECT *
FROM platzi.alumnos
WHERE id > (
SELECT COUNT(*)/2
FROM platzi.alumnos
);```

Mi solucion al reto

SELECT * 
    FROM platzi.alumnos
    OFFSET ( SELECT COUNT(*)/2 FROM platzi.alumnos );

En MySQL:

set @count = (select count(*)/2 from alumnos)

select * from 
(select row_number() over() as row_id, alumnos.* from alumnos)
as alumnos_rows 
where row_id > @count

Me topé con que mysql no permite en argumentos limists u offset datos que no sean constantes, por eso seteo primero el count

Con el DISTINCT le diré que me traiga valores sin duplicarlos, con el ORDER BY colegiatura DESC lo que hago es ordenarlo de manera descendente y con el LIMIT 2 lo que hago es decirle que me traiga solo 2 y el OFFSET 1 le digo que se salte un row.

SELECT DISTINCT colegiatura
FROM platzi.alumnos
ORDER BY colegiatura DESC
LIMIT 2 OFFSET 1

La linea de código que muestro mas abajo y que aparece en el código de la clase; por los resultados me parece que es redundante y no esta causando ningún efecto porque la columna “tutor_id” muestra cualquier id no solo los 20. Ejecute el código sin esta línea y da el mismo resultado.

WHERE tutor_id=20

EL PRIMER EJEMPLO
Me pase tiempo analizando esto, tiene que ver con conceptos fundamentales de SQL, y no lo entendía, ahí va la explicacion:

  1. La primera parte :

SELECT DISTINCT colegiatura
FROM platzi.alumnos AS a1

Crea una tabla con los siguientes valores:

[3000,2000,2300,4500,3500,5000,2500,4800]

  1. Luego el WHERE por concepto, compara fila por fila un valor, es decir manda el 1er valor a la subconsulta (3000), luego el segundo (2000) y así sucesivamente. En este caso, espera un 2:

WHERE 2 = (Subconsutta)

  1. La subconsulta:

SELECT COUNT(DISTINCT colegiatura)
FROM platzi.alumnos AS a2
WHERE a1.colegiatura <= a2.colegiatura

Es la misma que la primera, y lo que hace es comparar cada valor que le llega de la columna colegiatura con todos los valores de la misma columna:

Y por último, recien actúa el COUNT, por lo que la subconsulta devuelve un valor de número, haciendo que el WHERE 2 = 2 se cumpla.

Es un proceso innecesariamente largo, pero ayuda a comprender en que orden se ejecutan las sentencias

Me di cuenta que muchas personas piensan que el OFFSET debe usarse con un LIMIT, cosa que no es cierta, no es necesario.

  • El OFFSET de por sí ya se salta el número de registros que le pongas.

  • El LIMIT te muestra la cantidad de tuplas que quieras desde el inicio.

  • Combinándolos, puedes saltarte algunas tuplas con OFFSET y mostrar la cantidad que quieras después de estas filas saltadas con LIMIT.

Otra opción:

SELECT * FROM platzi.alumnos
OFFSET 500 ROWS
FETCH FIRST 500 ROWS ONLY```

empezó muy rudo con todo yo apenas entiendo algo de sql =(

Ejercicios.


--------------------------------------------------------
--Ejercicio 1
SELECT 
colegiatura
,count(colegiatura) Cuenta_Colegiatura
FROM [HAHM].[dbo].[platzialumnos]
Group by 
colegiatura 
order by 
colegiatura desc 
OFFSET  1 ROWS 
FETCH NEXT 1 ROWS ONLY 

---------------------------------------------------------
--Ejercicio 2

SELECT 
colegiatura
,tutor_id
,count(colegiatura) Cuenta_Colegiatura
FROM [HAHM].[dbo].[platzialumnos]

where tutor_id = 20

Group by 
colegiatura 
,tutor_id
order by 
colegiatura desc 
OFFSET  1 ROWS 
FETCH NEXT 1 ROWS ONLY 

---------------------------------------------------------
--Ejercicio 3

SELECT 
*
FROM [HAHM].[dbo].[platzialumnos] A 
inner join (SELECT 
					colegiatura
					,tutor_id
					,count(colegiatura) Cuenta_Colegiatura
					FROM [HAHM].[dbo].[platzialumnos]
					where tutor_id = 20
					Group by 
					colegiatura 
					,tutor_id
					order by 
					colegiatura desc 
					OFFSET  1 ROWS 
					FETCH NEXT 1 ROWS ONLY ) b on A.colegiatura = b.colegiatura
					

---------------------------------------------------------
--Ejercicio 4
SELECT 
*
FROM [HAHM].[dbo].[platzialumnos] A 
where colegiatura = (SELECT 
					colegiatura
				    FROM [HAHM].[dbo].[platzialumnos]
					where tutor_id = 20
					Group by 
					colegiatura 
					order by 
					colegiatura desc 
					OFFSET  1 ROWS 
					FETCH NEXT 1 ROWS ONLY ) 

Lo resolví de la siguiente manera, si entendí bien el ejercicio es mostrar la segunda mitad de la tabla, de 500 a 1000.

SELECT *
FROM platzi.alumnos
LIMIT 501 OFFSET 499;
SELECT * 
FROM platzi.alumnos
WHERE id > 499;

código de la clase:

select distinct colegiatura
from platzi.alumnos as a1
where 2 = (
	select count(distinct colegiatura)
	from platzi.alumnos a2
	where a1.colegiatura <= a2.colegiatura
)

select distinct colegiatura
from platzi.alumnos
where tutor_id = 20
order by colegiatura desc
limit 1 offset 1

select *
from platzi.alumnos as datos_alumnos
inner join (
	select distinct colegiatura
	from platzi.alumnos
	where tutor_id = 20
	order by colegiatura desc
	limit 1 offset 1
) as segunda_mayor_colegiatura
on datos_alumnos.colegiatura = segunda_mayor_colegiatura.colegiatura

select *
from platzi.alumnos
where colegiatura = (
	select distinct colegiatura
	from platzi.alumnos
	where tutor_id = 20
	order by colegiatura desc
	limit 1 offset 1
)

Primera opcion: saltando la primera mitad del total de registros

SELECT * 
FROM platzi.alumnos
OFFSET (
	SELECT COUNT(id)/2 FROM platzi.alumnos
);

Segunda opcion: Agregar el row_id de la anterior clase y usar un between entre el total de registros sobre 2 y el total de registros

SELECT *
FROM (
	SELECT ROW_NUMBER() OVER() AS row_id, *
	FROM platzi.alumnos
) AS A1
WHERE row_id 
BETWEEN (SELECT COUNT(id)/2 FROM platzi.alumnos)
AND (SELECT COUNT(id) FROM platzi.alumnos)

-- PARA RESOLVER EL RETO ENCONTRÉ UNA SOLUIÓN MUY SENCILLA

-- SIMPLEMENTE CONTAR LOS REGISTROS DE LA TABLA
SELECT COUNT(id)
FROM platzi.alumnos;

-- VEMOS QUE HAY 1000 REGISTROS

-- ENTONCES FILTRO LOS RESULTADOS DONDE EL ID SEA >= 501
-- ASÍ TRAIGO EXACTAMENTE LA SEGUNDA MITAD DE LA TABLA
SELECT *
FROM platzi.alumnos
WHERE id >= 501;

Resolución del Reto

Así fue como lo hice yo:

SELECT * 
FROM platzi.alumnos
ORDER BY alumnos.id ASC
OFFSET (
		SELECT COUNT(*)/2
		FROM platzi.alumnos
		);

Solución al reto, 2 formas distintas.

SELECT * 
FROM platzi.alumnos
OFFSET ( SELECT COUNT(*)/2
		FROM platzi.alumnos
);
SELECT *
FROM platzi.alumnos
WHERE id > (
	SELECT COUNT(*)/2 
	FROM platzi.alumnos
);

Del reto, con un combo de LIMIT/OFFSET

/* Con un LIMIT */
SELECT * from platzi.alumnos LIMIT (
SELECT COUNT (id)/2 from Platzi.alumnos
) 
OFFSET (
 SELECT COUNT (id)/2 from Platzi.alumnos)  

Otra forma de hacerlo

SELECT 
	MAX(A1.colegiatura) as segundo_mas_alto
FROM platzi.alumnos as A1
WHERE A1.price not in (
	SELECT max(A.colegiatura) 
	FROM platzi.alumnos as A
);

Leaving mine over here

SELECT ROW_NUMBER() OVER() AS row_id, *
FROM platzi.alumnos
OFFSET(
	SELECT COUNT(*)/2
	FROM platzi.alumnos
);

Con ayuda de Chat GPT. Tenía la idea de hacer los parámetros LIMIT y OFFSET dinámicos pero no tenía muy claro cómo hacerlo:

SELECT *
FROM your_table
ORDER BY some_column -- Replace "some_column" with the column you want to order the rows by
LIMIT (SELECT CEILING(COUNT(*) / 2) FROM your_table) OFFSET (SELECT CEILING(COUNT(*) / 2) FROM your_table);

Solución:

SELECT *
FROM platzi.alumnos
OFFSET(
SELECT COUNT(ID)/2
FROM platzi.alumnos);

SELECT *
FROM platzi.alumnos
WHERE id >500

En los dos últimos ejemplos no se filtra correctamente la información para el tutor con id igual a 20. Para corregir esto, en el primero de estos ejemplos, se debe extraer la sentencia WHERE del subquery y llevarla al final del query principal:

SELECT *
FROM platzi.alumnos AS datos_alumnos
INNER JOIN (
	SELECT DISTINCT colegiatura
	FROM platzi.alumnos
	ORDER BY colegiatura DESC
	LIMIT 1 OFFSET 1
) AS segunda_mayor_colegiatura
ON datos_alumnos.colegiatura = segunda_mayor_colegiatura.colegiatura
WHERE tutor_id = 20;

En el segundo ejemplo, se debe eliminar la sentencia WHERE del subquery y agregar la sentencia AND, con el filtro, al query principal:

SELECT *
FROM platzi.alumnos AS datos_alumnos
WHERE colegiatura = (
	SELECT DISTINCT colegiatura
	FROM platzi.alumnos
	ORDER BY colegiatura DESC
	LIMIT 1 OFFSET 1
) AND tutor_id = 20;

EL RETO

select *
from platzi.alumnos
where id >= ((select count(id) as numero_alumnos
	  from platzi.alumnos)/2);

Muy buena la clase, resalto lo que dijo el profe “Aquí es donde se pone interesante hacer cardio con SQL” hahahahaha

Realicé tres formas de listar la segunda mitad de la tabla no muy optimas, pero lo hice!!

– El codigo trae el LISTADO de la segunda mitad de la tabla
SELECT *
FROM platzi.alumnos
OFFSET (SELECT (COUNT(id)/2) FROM platzi.alumnos)

– El codigo trae el LISTADO de la segunda mitad de la tabla de diferente forma al anterior
SELECT *
FROM platzi.alumnos
WHERE id >=(
SELECT COUNT (colegiatura)
FROM platzi.alumnos
)/2

– El codigo trae el LISTADO de la segunda mitad de la tabla de diferente forma al anterior
SELECT *
FROM platzi.alumnos
WHERE id BETWEEN (
SELECT COUNT (colegiatura)
FROM platzi.alumnos
)/2
AND
(
SELECT COUNT (colegiatura)
FROM platzi.alumnos
)

SELECT 	*
FROM	platzi.alumnos
WHERE 	id > 500
;

Traer la segunda mitad de la tabla

SELECT *
FROM platzi.alumnos
OFFSET (SELECT COUNT(1)/2 FROM platzi.alumnos);

SELECT TOP 50 PERCENT *
FROM platzi.alumnos

En SQL Server es la forma más facil de obtener la segunda mitad de los registros de la tabla en un orden por default ascendente (ASC)

La solución fácil es la siguiente

SELECT * FROM platzi.alumnos LIMIT 500 OFFSET 500;

No obstante tiene un fallo, pues, sabemos a priori que la DB tiene mil registros; una opción más dinámica es con el siguiente query:

SELECT * FROM platzi.alumnos
WHERE id > (
	SELECT COUNT(id)/2
	FROM platzi.alumnos
);

SEGUNDO RETO:

SELECT *
FROM platzi.alumnos
OFFSET ( SELECT COUNT(*)/2 FROM platzi.alumnos );

SELECT *
FROM (
SELECT ROW_NUMBER() OVER() AS row_id, *
FROM platzi.alumnos
)
AS alumnos_with_row_num
WHERE row_id >= 500;

Así obtuve la segunda parte de la tabla

SELECT * from alumnos
LIMIT (SELECT count(*)/2 from alumnos) 
OFFSET (SELECT count(*)/2 from alumnos);

RETO
Así quedó mi Query

SELECT *
FROM platzi.alumnos
OFFSET (
	SELECT COUNT(*)/2
	FROM platzi.alumnos
);

El segundo más alto también funciona así:

select distinct colegiatura 
from platzi.alumnos as a1
where 1 = (
	select count(distinct colegiatura)
	from platzi.alumnos as a2
	where a1.colegiatura<a2.colegiatura
)

donde con el where =1 se busca aquel valor de colegiatura que solo tenga 1 mayor a él mismo. En este caso sale 4800 ya que solo tiene al 5000 como único valor mayor.

Para SQL Server

-- METODO 2
-- SEGUNDA COLEGIATURA EN ORDEN DESC CON FETCH NEXT
USE [platzi]
SELECT DISTINCT colegiatura AS [segunda colegiatura]
FROM platzi.alumnos
ORDER BY colegiatura DESC OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY
GO


-- SEGUNDA COLEGIATURA DE UN TUTOR
USE [platzi]
SELECT 
	DISTINCT colegiatura AS [segunda colegiatura], 
	tutor_id AS tutor
FROM platzi.alumnos
WHERE tutor_id=20
ORDER BY colegiatura DESC OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY
GO


-- METODO 3
-- DATOS DE LAS PERSONAS CON LA SEGUNDA COLEGIATURA EN ORDEN DESC CON INNER JOIN
USE [platzi]
SELECT id, nombre, apellido, colegiatura, segunda_colegiatura
FROM
	platzi.alumnos AS datos_alumnos
	INNER JOIN 
	(
		SELECT DISTINCT colegiatura AS segunda_colegiatura
		FROM platzi.alumnos
		ORDER BY colegiatura DESC OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY
	) AS segunda_mayor_colegiatura ON datos_alumnos.colegiatura = segunda_mayor_colegiatura.segunda_colegiatura
GO

Me salió así, en mySQL no pude hacer una subquery para el limit y el offset

SELECT *
FROM platzi.alumnos AS A
JOIN (SELECT ROW_NUMBER() OVER() AS row_id, id FROM platzi.alumnos) AS B
ON A.id = B.id
WHERE row_id > (SELECT COUNT(*)/2 FROM platzi.alumnos);

para los que estan siquiendo las clases del profesor con Mysql quedaria algo asi.

SELECT \* FROM ( SELECT ROW\_NUMBER() OVER() AS ROW\_ID,\* FROM lfa1)as prov\_ROW\_num WHERE ROW\_ID between 1 and 5; \--use otra tabla y otra base de datos
select * from alumnos
order by id asc limit (
 select count (*) from alumnos)/2 
offset (select count (*) from alumnos )/2;

Yo lo hago en SQL Server y me pareció interesante buscar como guardar la mitad de los registros en una variable:

Mi Query

SELECT *
FROM platzi.alumnos
WHERE alumnos.id >= 500;

SELECT *
FROM platzi.alumnos
WHERE id >= (
SELECT COUNT(*) / 2
FROM platzi.alumnos
);

Reto:

Mi solucion al reto:

En este código hay un error:

SELECT *
FROM platzi.alumnos AS datos_alumnos
WHERE colegiatura = (
	SELECT DISTINCT colegiatura
	FROM platzi.alumnos
	WHERE tutor_id = 20
	ORDER BY colegiatura DESC
	LIMIT 1 OFFSET 1
);

Para que nos arroje el resultado realmente por tutor_id = 20 se debe hacer de la siguiente manera:

SELECT *
FROM platzi.alumnos AS datos_alumnos
WHERE colegiatura = (
	SELECT DISTINCT colegiatura
	FROM platzi.alumnos
	ORDER BY colegiatura DESC
	LIMIT 1 OFFSET 1
)AND tutor_id = 20;

El WHERE tutor_id = 20 lo debemos dejar por fuera para que funcione:

SELECT *
FROM platzi.alumnos AS datos_alumnos
INNER JOIN (
	SELECT DISTINCT colegiatura
	FROM platzi.alumnos
	ORDER BY colegiatura DESC
	LIMIT 1 OFFSET 1
) AS segunda_mayor_colegiatura
ON datos_alumnos.colegiatura = segunda_mayor_colegiatura.colegiatura
WHERE tutor_id = 20;
-- Segunda mitad de la tabla
SELECT * --1
FROM platzi.alumnos
OFFSET (SELECT COUNT(*) / 2 FROM platzi.alumnos);



SELECT * --2
FROM platzi.alumnos
WHERE id >= (
    SELECT  COUNT(*) / 2
    FROM platzi.alumnos
);
<select * from platzi.alumnos
limit (select count(*) from platzi.alumnos)/2 OFFSET (select count(*) from platzi.alumnos)/2;> 

En Sql Server

SELECT *
FROM alumnos datos_alumnos
WHERE colegiatura = (
	SELECT DISTINCT colegiatura
	FROM alumnos
	ORDER BY colegiatura DESC
	OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY
)
SELECT *
FROM alumnos d_alumnos
INNER JOIN (
	SELECT DISTINCT colegiatura
	FROM alumnos
	WHERE tutor_id = 20
	ORDER BY colegiatura DESC
	OFFSET 1 rows FETCH NEXT 1 ROWS ONLY
) segunda_mayor_colegiatura
ON d_alumnos.colegiatura = segunda_mayor_colegiatura.colegiatura;

Respuesta al reto:

SELECT *
FROM platzi.alumnos
ORDER BY colegiatura
LIMIT (SELECT COUNT(*) FROM platzi.alumnos) / 2 OFFSET (SELECT COUNT(*) FROM platzi.alumnos) / 2;

Hola,
A continuación mi solución al RETO 2.

SELECT *
FROM (
	SELECT ROW_NUMBER() OVER() AS row_id, *
	FROM platzi.alumnos 
) AS alumnos_with_row_num
WHERE row_id <= (SELECT COUNT (id)/2
				 FROM platzi.alumnos);

Mi solución fue muy literal pero creería que esta bien, Nos dicen " tabla de la segunda mitad "

  1. lo primero que hice fue cuantos datos habían. y me guie por la fila ID
    SELECT COUNT (id)
    FROM platzi.alumnos;

sabiendo que son 1000 datos , voy a solo mostrar los 500 para arriba

2)SELECT *
FROM platzi.alumnos
OFFSET 499
LIMIT 1000

SELECT * 
FROM platzi.alumnos
WHERE id <= (SELECT COUNT(id) / 2 FROM platzi.alumnos)
SELECT DISTINCT colegiatura AS "El segundo mayor" FROM platzi.alumnos
ORDER BY alumnos.colegiatura DESC
OFFSET 1 LIMIT 1
;

dejo mi solucion al reto

select *
from platzi.alumnos as alumnos
where colegiatura < (
	select  distinct colegiatura
	from platzi.alumnos
	order by colegiatura desc
	limit 1 offset 2
)
order by colegiatura desc;

Mis 2 soluciones al reto propuesto por el profesor

no. 1:

SELECT *
FROM platzi.alumnos
WHERE id BETWEEN (
		SELECT id
		FROM platzi.alumnos
		ORDER BY id DESC
		LIMIT 1 )/2 
	AND
		(
		SELECT id
		FROM platzi.alumnos
		ORDER BY id DESC
		LIMIT 1 );

no. 2:

SELECT * 
FROM platzi.alumnos
OFFSET (
		SELECT id
		FROM platzi.alumnos
		ORDER BY id DESC
		LIMIT 1 )/2 
LIMIT (
		SELECT id
		FROM platzi.alumnos
		ORDER BY id DESC
		LIMIT 1 )/2 

Mi solución

SELECT *
FROM platzi.alumnos
WHERE id<=(
	SELECT COUNT(*)/2 AS total
	FROM platzi.alumnos);
	

Mi codigo para resolverlo, fue sencillo pero me dio el resultado
Select *
FROM platzi.alumnos
LIMIT 500 OFFSET 500

Mi aporte al primer ejercicio, de una manera más fácil y simplificada es la siguiente:

SELECT DISTINCT colegiatura
FROM platzi.alumnos
ORDER BY colegiatura DESC
OFFSET 1 LIMIT 1

A resaltar que el OFFSET tiene mejor rendimeinto que el WHERE en esta consulta

<SELECT * 
FROM platzi.alumnos
WHERE id > (
	SELECT COUNT(id)/2
	FROM platzi.alumnos
);

SELECT * 
FROM platzi.alumnos
OFFSET (
	SELECT COUNT(id)/2
	FROM platzi.alumnos
);> 

Varios caminos conducen a Roma xD

SELECT *
FROM platzi.alumnos
WHERE id >= (
SELECT COUNT (id)
FROM platzi.alumnos
)/2;

Varios caminos conducen a Roma xD SELECT * FROM platzi.alumnos WHERE id >= ( SELECT COUNT (id) FROM platzi.alumnos )/2;

Reto


-- Primera forma
SELECT * FROM alumnos
WHERE id BETWEEN (
	SELECT COUNT(id)/2
	FROM alumnos
) AND (
	SELECT COUNT(id) 
	FROM alumnos
);

-- Segunda Forma
WITH conteo AS (
	SELECT COUNT(id)/2 mitad, COUNT(id) total 
	FROM alumnos
)
SELECT * FROM alumnos,conteo
WHERE id BETWEEN mitad AND total;

-- Tercera forma
SELECT * FROM alumnos
OFFSET (
	SELECT (COUNT(id)-1)/2 
	FROM alumnos
)

Esta es la variante que mas rápido se ejecuta en SQL Server de todas las que probé:

select *
from (
	select *, ROW_NUMBER() over(order by (select null)) rno
	from alumnos a
) b
where rno > ((select count(*) from alumnos) / 2)

SQL Server

DECLARE @COUNT INT = (SELECT	COUNT(*)/2	FROM	Platzi.Alumnos)
SELECT	* 
FROM	(
			SELECT ROW_NUMBER() OVER(ORDER BY Colegiatura) AS Row_Id, * 
			FROM Platzi.Alumnos
		)	AS AlumnosWithRowNumber WHERE Row_Id >= @COUNT

MI RESUMEN DE LA CLASE EN CODIGO SQL:

//Traer la segunda colegiatura mas alta de la base de datos

SELECT DISTINCT colegiatura
FROM platzi.alumnos AS a1
WHERE 2 = (
SELECT COUNT (DISTINCT colegiatura)
FROM platzi.alumnos a2
WHERE a1.colegiatura <= a2.colegiatura
);

//Muestra las colegiaturas ordenadas de forma descendente.
SELECT DISTINCT colegiatura
FROM platzi.alumnos
ORDER BY colegiatura DESC;

//Muestra la colegiatura mas alta
SELECT DISTINCT colegiatura
FROM platzi.alumnos
ORDER BY colegiatura DESC
LIMIT 1 OFFSET 1;

//Muestra la segunda colegiatura mas alta
SELECT DISTINCT colegiatura, tutor_id
FROM platzi.alumnos
WHERE tutor_id = 20
ORDER BY colegiatura DESC
LIMIT 1 OFFSET 1;

//Muestra toda la informacion de la segunda colegiatura mas alta
SELECT *
FROM platzi.alumnos AS datos_alumnos
INNER JOIN(
SELECT DISTINCT colegiatura
FROM platzi.alumnos
WHERE tutor_id = 20
ORDER BY colegiatura DESC
LIMIT 1 OFFSET 1
) AS segunda_mayor_colegiatura
ON datos_alumnos.colegiatura = segunda_mayor_colegiatura.colegiatura;

SELECT *
FROM platzi.alumnos AS datos_alumnos
WHERE colegiatura = (
SELECT DISTINCT colegiatura
FROM platzi.alumnos
WHERE tutor_id = 20
ORDER BY colegiatura DESC
LIMIT 1 OFFSET 1
);

TAREA CLASE ANTERIOR:

Traer los primeros 5 registros de la tabla

SELECT *
FROM platzi.alumnos
FETCH FIRST 5 ROW ONLY;

Mi solución
.
.
.
.

select * from alumnos where id >= (select id from alumnos order by id desc limit 1)/2;

Creo que aunque un poco sencilla, es efectiva:

select *
from platzi.alumnos
limit 500 offset 500;

La cláusula DISTINCT hace que la consulta omita los resultados de la consulta duplicados. La cláusula DISTINCT se aplica a valores duplicados para todos los campos devueltos especificados por la cláusula SELECT

11. El segundo más alto

SELECT DISTINCT colegiatura
FROM platzi.alumnos AS a1
WHERE 2 = (
	SELECT COUNT (DISTINCT colegiatura)
	FROM platzi.alumnos a2 
	WHERE a1.colegiatura <= a2.colegiatura
);

SELECT DISTINCT colegiatura, tutor_id
FROM platzi.alumnos
WHERE tutor_id = 20
ORDER BY colegiatura DESC 
LIMIT 1 OFFSET 1;

SELECT
FROM platzi.alumnos AS datos_alumnos
INNER JOIN(
	SELECT DISTINCT colegiatura
	FROM platzi.alumnos
	WHERE tutor_id = 20
	ORDER BY colegiatura DESC
	LIMIT 1 OFFSET 1

)AS segunda_mayor_colegiatura
ON datos_alumnos.colegiatura = segunda_mayor_colegiatura.colegiatura;

SELECT *
FROM platzi.alumnos AS datos_alumnos 
WHERE colegiatura = (
	SELECT DISTINCT colegiatura
	FROM platzi.alumnos
	WHERE tutor_id = 20 
	ORDER BY colegiatura DESC
	LIMIT 1 OFFSET 1
);

SELECT *
FROM platzi.alumnos AS datos_alumnos
WHERE colegiatura = (
    SELECT MAX(colegiatura)
    FROM platzi.alumnos
    WHERE tutor_id = 20
);
 
 
-- RETO

SELECT *
FROM platzi.alumnos
OFFSET (SELECT COUNT(*) FROM platzi.alumnos) / 2;

SELECT *
FROM platzi.alumnos
LIMIT (SELECT COUNT(*) FROM platzi.alumnos) / 2 OFFSET (SELECT COUNT(*) FROM platzi.alumnos) / 2;

SELECT *
FROM (
    SELECT *, NTILE(2) OVER (ORDER BY (SELECT NULL)) AS half
    FROM platzi.alumnos
) AS half_alumnos
WHERE half = 2;

WITH ranked_alumnos AS (
  SELECT *, PERCENT_RANK() OVER (ORDER BY (SELECT NULL)) AS rank
  FROM platzi.alumnos
)
SELECT *
FROM ranked_alumnos
WHERE rank > 0.5;

Consulta para averiguar el número de valores únicos de ‘colegiatura’ en la tabla ‘alumnos’

SELECT COUNT(DISTINCT colegiatura)
FROM platzi.alumnos;

Outcome 8

  1. Creé una Tabla llamada ‘DistinctAmounts’. Esta tabla selecciona los montos distintos de colegiatura de la tabla platzi.alumnos y los ordena en orden descendente.
  2. La consulta principal selecciona colegiatura de la tabla ‘DistinctAmounts’
  3. Se utiliza OFFSET para omitir la primera mitad de las filas en la tabla ‘DistinctAmounts’. La subconsulta calcula el número total de filas en ‘DistinctAmounts’ y lo divide por 2 para determinar el desplazamiento.
WITH DistinctAmounts AS (
    SELECT DISTINCT colegiatura
    FROM platzi.alumnos
    ORDER BY colegiatura DESC
)
SELECT colegiatura
FROM DistinctAmounts
OFFSET (SELECT COUNT(*) FROM DistinctAmounts) / 2;

Outcome

1- 3000
2- 2500
3- 2300
4- 2000

SELECT *
FROM platzi.alumnos 
WHERE id >= (SELECT COUNT(*) FROM platzi.alumnos)/2 ;

//Traer la segunda mitad de la tabla.

//OPCION 1

SELECT *

FROM platzi.alumnos

OFFSET 500;

//OPCION 2

SELECT *

FROM (

SELECT ROW_NUMBER() OVER() AS row_id,*

FROM platzi.alumnos

) AS alumnos_with_row_num

WHERE row_id>(

SELECT COUNT(*)/2

FROM platzi.alumnos

)

Para los que utilizan SQL Server, seria de esta forma.

SELECT
ROW_NUMBER() OVER(ORDER BY TIK.TIK_ID) AS ID_ROW,
TIK.*
FROM
TICKET AS TIK
ORDER BY ID_ROW ASC
OFFSET 99 ROWS
FETCH NEXT 101 ROWS ONLY

En la consulta se esta realizando una nueva columna de enumeracion pero solo por los 100 ultimos registros de la tabla y luego la combino con la misma tabla pero solo para que traiga todo la tabla y la nueva columna enumerando a los registros seleccionados.

SELECT
ID_ROW.ID_ROW,
ALM.*
FROM
( SELECT
ROW_NUMBER() OVER() AS ID_ROW,
ALUM.*
FROM
ALUMNOS AS ALUM
WHERE
id > 900 ) AS ID_ROW
RIGHT JOIN
ALUMNOS AS ALM
ON
(
ALM.ID=ID_ROW.ID)
LIMIT 5

SELECT DISTINCT colegiatura
FROM platzi.alumnos
ORDER BY colegiatura DESC
OFFSET 1 LIMIT 1;

El primer query lo veo complicarse demasiado en vano.

Estas son mis propuestas de solución a mostrar solo la 2da mitad de la tabla

/*Propuesta 1*/
SELECT *
FROM platzi.alumnos AS datos_alumnos
WHERE ( 
	SELECT COUNT (id)
	FROM platzi.alumnos
)/2 < id ;

/*Propuesta 2*/
SELECT *
FROM platzi.alumnos
ORDER BY id
LIMIT (SELECT COUNT(id) FROM platzi.alumnos)/2
OFFSET (SELECT COUNT(id) FROM platzi.alumnos)/2;

/*Propuesta 3*/
SELECT *
FROM platzi.alumnos
ORDER BY id DESC
FETCH FIRST ((SELECT COUNT(id) FROM platzi.alumnos)/2) ROWS ONLY;

YO lo haria asi:

#Forma 1

SELECT * FROM platzi.alumnos
WHERE id>=(
	SELECT (COUNT(DISTINCT id))/2 As A
	FROM platzi.alumnos
)

# Forma 2 


SELECT * FROM platzi.alumnos
OFFSET 500
FETCH FIRST 500 ROWS ONLY;

Reto: Traer la segunda mitad de los registro de la tabla

SELECT *
FROM platzi.alumnos
ORDER BY id
OFFSET (SELECT COUNT(*) FROM platzi.alumnos) / 2
FETCH FIRST ((SELECT COUNT(*) FROM platzi.alumnos) / 2) ROWS ONLY;

SELECT *
FROM platzi.alumnos
ORDER BY id
OFFSET (SELECT COUNT(*) FROM platzi.alumnos) / 2
LIMIT ((SELECT COUNT(*) FROM platzi.alumnos) / 2);

SELECT *
FROM platzi.alumnos
ORDER BY id
OFFSET (SELECT COUNT(*) FROM platzi.alumnos) / 2;

Usé un OFFSET para saltar las filas y un subquery para determinar la mitad de la tabla

WITH avg_colegiatura AS (
    SELECT AVG(colegiatura) AS promedio
    FROM platzi.alumnos
    WHERE tutor_id = 20
),
filtered_colegiatura AS (
    SELECT DISTINCT colegiatura
    FROM platzi.alumnos
    WHERE tutor_id = 20
    ORDER BY colegiatura DESC
    LIMIT 1 OFFSET 1
),
alumnos_data AS (
    SELECT *
    FROM platzi.alumnos
    WHERE colegiatura = (SELECT colegiatura FROM filtered_colegiatura)
)
SELECT alumnos_data.*,
    CASE
        WHEN (SELECT promedio FROM avg_colegiatura) <= colegiatura THEN 1
        ELSE 0
    END AS valores
FROM alumnos_data;

Yo sigo el curso con MariaDB.

la manera facil de ejecutar es;

SELECT * FROM alumnos 
LIMIT 500 OFFSET 500;

Pero lo interesante es hacerlo con COUNT().

En mariadb LIMIT no admite valores que sean variables

explore por los lados de prepared statements y funciono

PREPARE mitad_query FROM "SELECT * FROM alumnos  LIMIT ? OFFSET ?";
SET @limit = (select count(*)/2 from alumnos);
SET @offset = (select count(*)/2 from alumnos);
EXECUTE mitad_query USING @limit, @offset;

y la ejecucion esta aqui:

MariaDB [practico_sql]> EXECUTE mitad_query USING @limit, @offset;
+------+------------+-----------------+--------------------------------------+-------------+---------------------+------------+----------+
| id   | nombre     | apellido        | email                                | colegiatura | fecha_incorporacion | carrera_id | tutor_id |
+------+------------+-----------------+--------------------------------------+-------------+---------------------+------------+----------+
|  501 | Yance      | NULL            | [email protected]               |        3000 | 2018-03-07 17:59:38 |         23 |       15 |
|  502 | Claudius   | Draye           | [email protected]                 |        3500 | 2018-08-25 21:38:15 |         13 |       14 |

SELECT * FROM platzi.alumnos
LIMIT (
(SELECT COUNT(*) FROM platzi.alumnos)/2)
OFFSET (
(SELECT COUNT(*) FROM platzi.alumnos)/2);

Mi solución:

SELECT * 
FROM platzi.alumnos
OFFSET 0.5 * 
(SELECT max(id) 
FROM platzi.alumnos);

Tengo dos soluciones
–1
SELECT *
FROM platzi.alumnos
OFFSET (SELECT COUNT(id) /2 as filas
FROM platzi.alumnos) - 1 ;

–2
SELECT *
FROM platzi.alumnos
WHERE id >= (SELECT COUNT(id) /2 FROM platzi.alumnos);

SELECT * 
FROM platzi.alumnos 
OFFSET (SELECT COUNT(*)/2 from platzi.alumnos);

yo lo hice por BETWEEN y el resultado fue igual
SELECT *
FROM (
SELECT ROW_NUMBER() OVER() AS row_id, *
FROM platzi.alumnos
) AS alumnos_with_row_num
WHERE row_id BETWEEN 0 AND 10;

SELECT * FROM alumnos WHERE colegiatura = 4800 AND tutor_id  != 20;

Mi solución al reto :
SELECT *
FROM platzi.alumnos
WHERE id >= (
(SELECT COUNT(id)
FROM platzi.alumnos) / 2
);

si tengo el dato del tutor en mi codigo es porque es un dato importante para mi estudio, no?

Yo creo que agregaria este query.

SELECT *
FROM platzi.alumnos AS datos_alumnos
WHERE colegiatura = (
	SELECT DISTINCT colegiatura
	FROM platzi.alumnos
	ORDER BY colegiatura DESC
	LIMIT 1 OFFSET 1
)
AND tutor_id = (
	SELECT DISTINCT tutor_id
	FROM platzi.alumnos
	WHERE tutor_id = 20
);
<code> 
Select *
from platzi.alumnos
Where id >=500;