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 535

Preguntas 37

Ordenar por:

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

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

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

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

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.

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

Otra opción:

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

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 ) 

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
)

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;

Resolución del Reto

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;

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
);

Esta es mi solución al reto, son 2 formas: ![](https://static.platzi.com/media/user_upload/image-7b57926c-b55c-4fd4-8508-668d2ce8e04b.jpg)

Misolución al reto es la siguiente

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

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;

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.

se puede hacer de forma parcial, averiguando la cantidad de registro, sabiendo su mitad, mostrar los restantes. ![](https://static.platzi.com/media/user_upload/image-67dd16c2-e38a-48c1-83fc-aeb37b74d9b0.jpg)
Dos posibles soluciones: ```css SELECT * FROM platzi.alumnos WHERE id > (SELECT MAX(id) / 2 FROM platzi.alumnos); ``` ```css SELECT * FROM platzi.alumnos OFFSET CEIL((SELECT COUNT(*) FROM platzi.alumnos) / 2.0) ROWS; ```
SELECT \* FROM platzi.alumnos OFFSET(SELECT count(\*)/2 FROM platzi.alumnos)
SELECT \* FROM (SELECT ROW\_NUMBER() OVER() AS row\_id,\* FROM platzi.alumnos) alumnos\_with\_rows WHERE alumnos\_with\_rows.row\_id >(SELECT COUNT(ID) FROM platzi.alumnos)/2; SELECT \* FROM platzi.alumnos OFFSET (SELECT COUNT(ID) FROM platzi.alumnos)/2;
Mi query, la segunda mitad del resultado de la consulta de los alumnos con la segunda mayor colegiatura: ```txt select * from alumnos a2 where colegiatura =( select distinct colegiatura from alumnos a where tutor_id =20 order by colegiatura DESC limit 1 offset 1 ) offset (select count(id)/2 from alumnos a2 where colegiatura =( select distinct colegiatura from alumnos a where tutor_id =20 order by colegiatura DESC limit 1 offset 1 )) ```select \* from alumnos a2 where colegiatura =( select distinct colegiatura from alumnos a where tutor\_id =20 order by colegiatura DESC limit 1 offset 1 ) offset (select count(id)/2 from alumnos a2 where colegiatura =( select distinct colegiatura from alumnos a where tutor\_id =20 order by colegiatura DESC limit 1 offset 1 ))
Comparto mi codigo luego de muchos intentos SELECT \* FROM platzi.alumnos AS datos\_alumnos WHERE id > 499 AND colegiatura = ( SELECT DISTINCT colegiatura FROM platzi.alumnos ORDER BY colegiatura DESC LIMIT 1 OFFSET 1 );
```js SELECT * FROM PLATZI.ALUMNOS FETCH FIRST 5 ROWS ONLY; -- LIMITA AL PRIMER REGISTRO SELECT * FROM PLATZI.ALUMNOS LIMIT 5; -- FUNCIONES DE VENTANAS , WINDOWS FUNTIONS SELECT * FROM ( SELECT ROW_NUMBER() OVER() AS row_id, * FROM PLATZI.ALUMNOS ) AS alumnos_with_row_num; ``` ```js ```SELECT \* FROM PLATZI.ALUMNOS FETCH FIRST 5 ROWS ONLY; \-- LIMITA AL PRIMER REGISTRO SELECT \* FROM PLATZI.ALUMNOS LIMIT 5; \-- FUNCIONES DE VENTANAS , WINDOWS FUNTIONS SELECT \* FROM ( SELECT ROW\_NUMBER() OVER() AS row\_id, \* FROM PLATZI.ALUMNOS ) AS alumnos\_with\_row\_num;
Reto: `SELECT \* FROM platzi.alumnos OFFSET (SELECT (count(\*) / 2) FROM platzi.alumnos)`
SELECT *
FROM platzi.alumnos
LIMIT (
	SELECT COUNT(*)/2
	FROM platzi.alumnos
) OFFSET (
	SELECT COUNT(*)/2
	FROM platzi.alumnos
);
Yo hice esta: SELECT \* FROM platzi.alumnos WHERE id BETWEEN 500 AND 1000;
```js SELECT * FROM (SELECT ROW_NUMBER() OVER() as numero,* FROM platzi.alumnos) WHERE numero > (SELECT COUNT(*)/2 FROM platzi.alumnos) ```SELECT \* FROM (SELECT ROW\_NUMBER() OVER() as numero,\* FROM platzi.alumnos) WHERE numero > (SELECT COUNT(\*)/2 FROM platzi.alumnos)
Desafio completado: ![](https://static.platzi.com/media/user_upload/Screenshot%202024-04-17%2012.35.42-e6c6dc44-e676-4fc4-b9f4-6659f576ed65.jpg)
no entiendo que hace el WHERE 2 =
SELECT \* FROM platzi.alumnos OFFSET(SELECT COUNT(\*) / 2 FROM platzi.alumnos)
\--Obtener la segunda colegiatura mas alta SELECT DISTINCT colegiatura FROM platzi.alumnos ORDER BY colegiatura DESC LIMIT 1 OFFSET 1;
Otra forma de hacer la segunda colegiatura ```txt select max (colegiatura) as colegiatura from platzi.alumnos where colegiatura < ( select max (colegiatura) from platzi.alumnos ); ```Otra forma de hacer la segunda colegiatura
Otra forma de hacer la segunda colegiatura select max (colegiatura) as colegiatura from platzi.alumnos where colegiatura < ( select max (colegiatura) from platzi.alumnos );```txt ```
Cuando el profesor explica el ejemplo con INNER JOIN y yo elimino `WHERE tutor_id = 20 `no hay diferencia porque de igual manera la consulta se hace con todos los estudiantes que pagan de colegiatura 4800. Si estoy equivocado agradezco la observación ![](https://static.platzi.com/media/user_upload/image-3ed0ea44-1e25-4406-9a1f-9203a947a96a.jpg)
SELECT TOP 5 \* FROM alumnos

Reto:

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

otra forma de hacer el query: ```txt select * from platzi.alumnos where colegiatura = ( select distinct colegiatura from platzi.alumnos order by colegiatura desc offset 1 limit 1 ); ```select \* from platzi.alumnos where colegiatura = ( select distinct colegiatura from platzi.alumnos order by colegiatura desc offset 1 limit 1 );
select \* FROM ( SELECT ROW\_NUMBER() OVER() AS row\_id, \* FROM platzi.alumnos ) AS alumnos\_with\_row\_num fetch first 5 rows only; ;
Hola, les dejo mi solución al ejercicio de la clase anterior.```js SELECT * FROM ( SELECT *, ROW_NUMBER() OVER() row_id FROM alumnos )AS alumnos_with_row_nums WHERE row_id <= 5; SELECT * FROM alumnos ORDER BY id ASC LIMIT 5; ```
Aquí mi Query sé que hay mejores formas pero es trabajo honesto jaja SELECT \* FROM platzi.alumnos AS a1 INNER JOIN ( SELECT id FROM platzi.alumnos ORDER BY id DESC LIMIT ( SELECT COUNT (\*) FROM platzi.alumnos)/2) AS a2 ON a1.id = a2.id;
SELECT \* FROM platzi.alumnos WHERE id >( SELECT id FROM platzi.alumnos ORDER BY id DESC limit 1 )/2;
SELECT \* FROM platzi.alumnos WHERE id >( SELECT id FROM platzi.alumnos ORDER BY id DESC limit 1 )/2; No se me ocurrio usar count hasta que vi los comentarios

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

Hola, con esta consulta que pensé no sólo trae la segunda colegiatura más cara si no que, además, nos dice cuántos usuarios están pagando dicho valor.

<code> 
SELECT colegiatura, COUNT(colegiatura) AS cantidad_de_alumnos
FROM platzi.alumnos
GROUP BY colegiatura
ORDER BY colegiatura DESC
OFFSET 1
LIMIT 1;
SELECT \* FROM platzi.alumnos OFFSET 500 LIMIT 500
Mi solución fue la siguiente: ```js select distinct colegiatura from platzi.alumnos order by colegiatura desc limit 1 offset 1 ```select distinct colegiatura from platzi.alumnos order by colegiatura desc limit 1 offset 1 Pienso que es mas sencillo cuando sabes el lugar/posición exacta que queremos, y usando LIMIT, OFFSET y ORDER BY lo tendremos.
select \* from platzi.alumnos offset 500
SELECT *
FROM platzi.alumnos
ORDER BY colegiatura DESC
OFFSET (SELECT COUNT(*) FROM platzi.alumnos) / 2
FETCH NEXT (SELECT COUNT(*) FROM platzi.alumnos) / 2 ROWS ONLY;

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

Mi query

select *
FROM PLATZI.ALUMNOS
offset (
select count(id)
from platzi.alumnos)/2
limit (
select count(id)
from platzi.alumnos)/2;

Mi solución: ```js SELECT * FROM platzi.alumnos WHERE alumnos.id > (SELECT MAX (id) FROM platzi.alumnos)/2; ```SELECT \* FROM platzi.alumnos WHERE alumnos.id > (SELECT MAX (id) FROM platzi.alumnos)/2

Les comparto como resolví el ejercicio: seleccione todos los
registros de la tabla alumno y luego establecí la condición
de que el id sea mayor al id de la mitad de la tabla

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

Otra forma de hallar el segundo valor mas alto:

select max(colegiatura) as SegValMasAlto from platzi.alumnos
where not colegiatura = (
	select max(distinct(colegiatura)) from platzi.alumnos)
```js SELECT tb.* FROM (SELECT COUNT(*)/2 as mitad FROM platzi.alumnos) as td, platzi.alumnos AS tb WHERE tb.id > td.mitad ```SELECT tb.\* FROM (SELECT COUNT(\*)/2 as mitad FROM platzi.alumnos) as td, platzi.alumnos AS tb WHERE tb.id > td.mitad De esta forma saque la segunda mitad de la tabla.
Muy interesante tantas opciones, gracias

Y yo pensando que ya sabia sql 😿

SELECT colegiatura FROM platzi.alumnos OFFSET (SELECT COUNT(\*) FROM platzi.alumnos) / 2;
La parte de la tercera forma de hacer el segundo ejercicio donde dice en el subquery **where tutor\_id = 20** en realidad no afecta el resultado de la proyección pues al final el query arroja todos los estudiantes que pagan la segunda más alta colegiatura independiente del tutor. Si se quisiera que solo se muestren los alumnos que pagan la segunda más alta colegiatura de un tutor específico se tendría que añadir la cláusula **where tutor\_id = 20** después de la cláusula **ON** del join

Encontré dos posibles respuestas;

  1. En la primera usando el Where saco el Máximo del ID el cual es un Integer Autoincremental y PK y lo divido entre 2
  2. En la segunda hago algo similar pero en el offset esta vez con un conteo dividido 2 para que omita ese número específico de rows
Esta es mi solucion: ```js SELECT id, * FROM platzi.alumnos WHERE id > ( SELECT COUNT(id) / 2 FROM platzi.alumnos ); ``` Lo que se esta haciendo es tomar todos los valores en donde ID sea mayor a la mitad de IDs en la tabla completa, lo hice de esta manera pensando en que si se agregan valores a la tabla el query seguira siendo funcional ya que tomara siempre la mitad de lo que hay en la tabla.

En SQL server

SELECT colegiatura FROM(
	SELECT ROW_NUMBER() OVER(ORDER BY colegiatura DESC) AS row_id, *
	FROM (SELECT DISTINCT colegiatura FROM alumnos) AS dist_cole
) AS row_cole
WHERE row_id=2;
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
);