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

Egoísta (selfish)

18/29
Recursos

Aportes 146

Preguntas 19

Ordenar por:

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

o inicia sesión.

solución reto:

SELECT AVG(alumnos_por_tutor) AS promedio_alumnos
FROM(
SELECT CONCAT(t.nombre,' ',	t.apellido) AS tutor,
		COUNT(*)   AS alumnos_por_tutor
FROM platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t ON a.tutor_id=t.id

GROUP BY tutor	
ORDER BY alumnos_por_tutor DESC
) AS promedio
--Experimento-- 
--promedio de tutores por carrera--
SELECT AVG(dc.tutor_por_carrera)
FROM(
	-- seleciona cuantas tutorias realiza en una carrera--
SELECT 	CONCAT(t.nombre,' ',	t.apellido) AS tutor,
		COUNT(*) AS tutor_por_carrera,
		a.carrera_id
FROM platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t ON a.tutor_id=t.id 
			AND a.carrera_id=t.tutor_id
GROUP BY tutor, a.carrera_id	
ORDER BY tutor_por_carrera DESC) AS dc

Lo que hace este query es asumir que el tutor con el tutor_id X de cada alumno es otro alumno con el mismo id, por eso te muestra los nombres y apellidos de profesores cuando en la table esta información no está, solo tenemos los nombres y apellidos de alumnos. Saludos

SELECT	a.nombre,
		a.apellido,
		t.nombre,
		t.apellido
FROM	platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id;

Si no estoy mal, al hacer:

INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id

también estamos asumiendo que todos los 30 tutores son alumnos, pero no todos los alumnos son tutores ¿No?


-- Promedio General de alumnos por tutor 
SELECT AVG(n_alumnos) AS promedio_alumnos
FROM (
     SELECT COUNT(*) AS n_alumnos FROM alumnos
     GROUP BY tutor_id
         ) AS tabla_num_alumnos_por_tutor;

TIP: Si no les quedó claro el SELF JOIN

Era más sencillo si nos mostraba todos los campos primero al hacer el self join, ahí es evidente como se “cruzan” las tablas y el uso de las claves foráneas y primarias.

SELECT *
FROM platzi.alumnos AS a JOIN platzi.alumnos AS t 
	   ON a.tutor_id = t.id

A la izquierda (azul) está la tabla de alumnos y la derecha (amarillo) la tabla de “tutores” que en realidad es la misma tabla de alumnos, pero trae los datos del alumno que tenga el id del tutor que está a la izquierda. Ese join se lo ve claramente en color verde.

Dato extra: Los tutores son los primeros 30 estudiantes

SELF JOINS

  • Personalmente considero que a la hora de hacer self-joins es de especial importancia más que en otros casos el hecho de comentar el código
  • En este caso aclararía en el código que recurrí a esta técnica, ya que los tutores a la vez son alumnos, de ahí que puedo obtener toda la información de la propia tabla

RETO: Promedio de alumnos por tutor

Mi respuesta el ejercicio de promedio

SELECT round((SUM(qq.alumnos_por_tutor) / COUNT(tutor)),0) as promedio
FROM (
	SELECT CONCAT(t1.nombre, ' ', t1.apellido ) AS tutor,
		   COUNT(*) AS alumnos_por_tutor
		   
	FROM platzi.alumnos AS t0
	INNER JOIN platzi.alumnos AS t1 ON t0.tutor_id = t1.id
	GROUP BY tutor
) QQ;```

Un dia ayudando a un compañero describi que existe CONCAT_WS y me gusta mas que el CONCAT, sobre todo cuando tienes que unir muchos campos.

SELECT CONCAT_WS(' ', a.nombre, a.apellido) AS alumno,
		CONCAT_WS(' ', t.nombre, t.apellido) AS tutor
FROM platzi.alumnos AS a
INNER JOIN platzi.alumnos as t ON a.tutor_id = t.id;

Me costó mucho entenderlo, y tuve que ver algunos comentarios para este reto. Al final resultó de esta forma:

SELECT AVG(conteo.alumnos_por_tutor) AS promedio_alumnos
FROM(SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor, 
	COUNT(*) AS alumnos_por_tutor 
	FROM platzi.alumnos AS a INNER JOIN platzi.alumnos AS t ON (a.tutor_id = t.id)
	GROUP BY tutor) AS conteo
;

SELFISH


Selfjoins Hacer uniones entre columnas de la misma tabla.

Por lo que básicamente seleccionamos las columnas y les es asignamos sub tablas

SELECT a.nombre t.nombre

Asiganamos alias (a , t) a las nuevas tablas que queremos comparar, y ejecutamos el join

select a.nombre, a.apellido, t.nombre,t.apellido 
from platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t on a.tutor_id = t.id;

Comparto el reto

SELECT tutor_id, Min(nombre)
FROM platzi.alumnos
GROUP BY tutor_id
ORDER BY tutor_id;

  SELECT AVG(alumnos_por_tutor) as promedio
FROM (
	SELECT CONCAT(t.nombre,' ',	t.apellido) AS tutor, COUNT(*) AS alumnos_por_tutor
	FROM platzi.alumnos AS a
	JOIN 
		 platzi.alumnos AS t 
	ON a.tutor_id = t.id
	GROUP BY tutor
) As promedio

En el minuto 2:03 el resultado del Query NO ESTÁ ORDENADO ALFABETICAMENTE, esta ordenado es por tutor_id. Si se fijan, el registro 1 empieza por AL… y el registro 2 empieza por AD y alfabeticamente esta primero la D que la L.
.
Entonces para que quede ordenado alfabeticamente se debe asignar un alias al resultado de la funcion MIN y ordenar el query en base a ese alias, asi:

SELECT tutor_id,
	MIN (nombre) AS minimo
FROM platzi.alumnos
GROUP BY tutor_id
ORDER BY minimo; -- El resultado es el MIN ordenado alfabeticamente

Me costó un poco entenderlo la primera vez porque me puse a buscar nombre y apellido de los tutores y no los encontraba. A partir de los comentarios entendí que los tutores son los mismos alumnos. Volví a ver la clase y en el minuto 3:50 el profesor incorpora “el supuesto” de que los alumnos sean también los tutores y por lo tanto el tutor_id se corresponde con el id del alumno.

RETO

SELECT AVG(alumnos_por_tutor) AS promedio
FROM(SELECT CONCAT( t.nombre,'  ', t.apellido) AS tutor,
      count(*) AS alumnos_por_tutor
FROM platzi.alumnos AS a
INNER JOIN platzi.alumnos AS t on a.tutor_id=t.id
GROUP BY tutor
) AS promedio;

Hola! comparto mi solucion del ejercicio propuesto:

SELECT
	ROUND(AVG(conteo),1) AS prom_alumnos_por_tutor
FROM (SELECT 
			COUNT(DISTINCT id) AS conteo
			, tutor_id
		FROM platzi.alumnos
		GROUP BY tutor_id
	 ) AS num_alumnos_por_tutor

select avg(prom) as promedio
from (
select count(*) as prom
from platzi.alumnos
group by tutor_id
) tabla_prom

Mi solución del reto (postgreSQL):

SELECT AVG(cant_alumnos) AS promedio_alumnos_por_tutor
FROM(
SELECT CONCAT(t.nombre,' ', t.apellido) AS tutor, COUNT(*) cant_alumnos
FROM platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t
	ON a.tutor_id=t.id
GROUP BY tutor
	) AS alumnos_por_tutor

Tómalo:

with taux as (
select concat(t.nombre, ' ', t.apellido) as tutor, count(*) as alumni_per_tutor 
from platzi.alumnos a
inner join platzi.alumnos t on a.tutor_id = t.id
group by tutor)
select round(avg(alumni_per_tutor),2) from taux

Así lo hice y me quedó bien, toy felí 😃

select avg(conteo.alumnos_x_tutor) as promedio_general
	from(
		select concat(t.nombre, ' ', t.apellido) as tutor,
		count(*) as alumnos_x_tutor
		from platzi.alumnos as a
			inner join platzi.alumnos as t on a.tutor_id = t.id
		group by tutor
	) as conteo;
SELECT AVG(alumnos\_por\_tutor) AS alumnos\_promedio FROM( SELECT CONCAT (t.nombre, ' ', t.apellido) AS tutor, COUNT(\*) AS alumnos\_por\_tutor FROM platzi.alumnos AS a INNER JOIN platzi.alumnos AS t ON a.tutor\_id = t.id GROUP BY tutor ORDER BY alumnos\_por\_tutor DESC ) AS promedio;
Mi solución de la clase pasada: ```js SELECT MIN(nombre) FROM platzi.alumnos -- SELECT MIN(nombre), tutor_id FROM platzi.alumnos GROUP BY tutor_id ORDER BY tutor_id ```
Para sacar el promedio solicitado, no me es útil el INNER JOIN, a menos que haya entendido mal el ejercicio. Ví varias soluciones y algunas coinciden en ello.
select avg(al) from( select --concat(a.nombre, ' ',a.apellido)as alumno, concat(b.nombre, ' ',b.apellido)as tutor, count(\*) as al from platzi.alumnos as a inner join platzi.alumnos as b on a.tutor\_id=b.id group by tutor--, alumno order by al desc )as promedio;
-- Promedio general de alumnos por tutor
SELECT CONCAT(t.nombre,' ',t.apellido) AS tutor,
AVG(alumnos_conteo) AS alumnos_por_tutor
FROM (SELECT tutor_id, 
    COUNT(*) AS alumnos_conteo
    FROM platzi.alumnos
    GROUP BY tutor_id) AS a
INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
GROUP BY tutor
ORDER BY alumnos_por_tutor DESC;

Aquí mi aporte:

SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor,
       COUNT(*) AS alumnos_por_tutor,
       AVG(COUNT(*)) OVER () AS promedio_alumnos_por_tutor
FROM platzi.alumnos AS a
    INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
GROUP BY tutor
ORDER BY alumnos_por_tutor DESC
LIMIT 5;

Mi solución, lo hice de dos maneras. Esta con el último código de la clase

SELECT AVG(alumnos_por_tutor) AS promedio_alumnos_por_tutor
FROM (SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor,
		   COUNT(*) AS alumnos_por_tutor
	FROM platzi.alumnos AS a
		INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
	GROUP BY tutor		
	) AS cantidad;
	

Y esta más simplificada, solo cuento la cantidad de alumnos por tutor al agruparlos y saco el promedio de eso.

SELECT AVG(alumnos_por_tutor) AS promedio_alumnos_por_tutor
FROM (SELECT COUNT(*) AS alumnos_por_tutor
	  FROM platzi.alumnos
	  GROUP BY tutor_id
	 )AS cantidad;
---PROMEDIO DE ALUMNOS POR TUTOR--
SELECT AVG(alumnos_por_tutor) AS alumnos_promedio
FROM(
SELECT CONCAT (t.nombre, ' ', t.apellido) AS tutor,
COUNT(*) AS alumnos_por_tutor 
FROM platzi.alumnos AS a
INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
GROUP BY tutor
ORDER BY alumnos_por_tutor DESC
) AS promedio;

Reto: Promedio de tutores por carrera

SELECT AVG(tutores_unicos) AS Promedio_Tutores
FROM(
	SELECT platzi.carreras.carrera, t.tutores_unicos
		FROM(
			SELECT carrera_id, COUNT(DISTINCT tutor_id) AS tutores_unicos
			FROM platzi.alumnos
			GROUP BY carrera_id
			) AS t
		LEFT JOIN platzi.carreras ON t.carrera_id = platzi.carreras.id
)AS subconsulta

Se puede ignorar el Join, lo hice para ver cuantos tutores hay por carrera pero con la columna del nombre

--Promedio de alumnos por tutor

SELECT AVG(alumnos_por_tutor)
FROM(
	SELECT CONCAT (t.nombre, ' ', t.apellido) AS tutor, 
		   COUNT(*) AS alumnos_por_tutor
	FROM platzi.alumnos AS a
		INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
	GROUP BY tutor
	ORDER BY alumnos_por_tutor DESC
) AS subconsulta

Reto: Sacar el prodio de alumnos que existen por tutor

SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor,
       COUNT(*) AS alumnos_por_tutor,
       AVG(COUNT(*)) OVER() AS promedio_alumnos_por_tutor
FROM platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
	GROUP BY tutor
	ORDER BY alumnos_por_tutor DESC;

SELECT AVG(alumnos_por_tutor) AS promedio_alumnos_por_tutor
FROM (
    SELECT COUNT(*) AS alumnos_por_tutor
    FROM platzi.alumnos AS a
    INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
    GROUP BY t.id
) AS consulta_promedio_alumnos_por_tutor;```

Reto

SELECT avg(datos.alumnos_por_tutor)
FROM (SELECT CONCAT(t.nombre, ' ', t.apellido) as tutor,
	COUNT(*) as alumnos_por_tutor
	FROM platzi.alumnos as a
	INNER join platzi.alumnos AS t on a.tutor_id = t.id
	GROUP BY tutor) AS datos

Cuando el teacher realiza el siguiente codigo

SELECT	CONCAT(a.nombre, ' ', a.apellido) AS alumno,
		CONCAT(t.nombre, ' ', t.apellido) AS tutor
FROM	platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id

sale el nombre del alumno por cada tutor, pero no queda esta informacion en la misma fila, asi que para que por cada fila o organizar los nombres de todos los alumnos por tutor realice el siguiente codigo, por si alguien le llama la atencion.

SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor,
       (SELECT STRING_AGG(CONCAT(a.nombre, ' ', a.apellido), ', ')
        FROM platzi.alumnos AS a
        WHERE a.tutor_id = t.id) AS alumnos
FROM platzi.alumnos AS t;

--RETO CLASE SELFISH

SELECT AVG (promedio_alumnos.cantidad)
FROM 
	(SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor,
	COUNT(a.id) cantidad
	FROM platzi.alumnos a  INNER JOIN platzi.alumnos t ON t.id = a.tutor_id
	GROUP BY t.nombre, t.apellido) AS promedio_alumnos;

mi solucion

-- Selecciona el promedio de alumnos por tutor y lo renombra como "promedio"
SELECT AVG (alumnos_por_tutor) AS promedio
FROM (
    -- Selecciona el nombre y apellido del tutor y cuenta el número de alumnos asignados a cada tutor
    SElECT CONCAT ( t.nombre, ' ', t.apellido) AS tutor, 
           COUNT (*) AS alumnos_por_tutor
    FROM platzi.alumnos AS a
    -- Une la tabla de alumnos con la tabla de tutores en base al ID del tutor
    INNER JOIN platzi.alumnos AS t
    ON a.tutor_id = t.id
    -- Agrupa los resultados por tutor
    GROUP BY tutor
    -- Ordena los resultados en orden descendente por el número de alumnos
    ORDER BY alumnos_por_tutor DESC
) AS promedio_general; -- Renombra la subconsulta como "promedio_general"

Creo que esta opcion es mas eficiente

select 	concat(t.nombre,' ', t.apellido) as tutor,
		round(count(*) * 100.0 / (SELECT count(*) 
		FROM platzi.alumnos), 2) as porcentaje_por_tutor
from platzi.alumnos as t
	inner join platzi.alumnos as a on a.tutor_id = t.id
group by tutor
order by porcentaje_por_tutor  desc
limit 5

Mi respuesta al reto:

Me da un promedio de 33 estudiantes promedio por tutor.

SELECT
	ROUND(AVG(alumnos_tutor),0) AS alumnos_promedio_tutor
FROM
	(SELECT 
		CONCAT(t.nombre,' ',t.apellido) AS tutor,
		COUNT(*) alumnos_tutor
	FROM platzi.alumnos a
	INNER JOIN platzi.alumnos t
	ON a.tutor_id = t.id
	GROUP BY tutor
	ORDER BY alumnos_tutor DESC) AS alumnos_tutor;

Yo solo le veo utilidad en tablas recursivas.

Solucion PG admin

SELECT AVG (n_alumnos) AS promedio_alumnos
FROM (
	SELECT COUNT (*) AS n_alumnos FROM platzi.alumnos 
	GROUP BY tutor_id
) AS tabla_num_alumnos_por_tutor;

“me quedo grande muchachos, que bendición ve”

SELECT AVG(alumnos_por_tutor) AS CONCAT promedio_por_tutor
FROM (
CONCAT(t.nombre, ‘ ‘, t.apellido) AS tutor,
COUNT(*) AS alumnos_por_tutor
FROM platzi.alumnos AS a
INNER JOIN platzi.alumnos t
ON a.tutor_id=t .id
GROUP BY tutor
) AS alumnos_tutor;

SELECT AVG(alumnos por tutor) as promedio
FROM( SELECT CONCAT(t. nombre, ' ', t.apellido) AS tutor,
	COUNT(*) AS alumnos_por_tutor
	FROM platzi.alumnos AS a
		INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
	GROUP BY tutor
) AS data

select tutor_id,
MIN (nombre)
from platzi.alumnos
group by tutor_id
order by tutor_id

mi solucion al reto del promedio de alumnos por tutor

select avg(alumnos_tutor.cantidad)  from 
	(select  
		concat(t.nombre, ' ',t.apellido) as tutor,
		count(a.id) cantidad
		from alumnos a 
	inner join alumnos t on t.id = a.tutor_id
	group by t.nombre, t.apellido) as alumnos_tutor;

Mi solución al reto de promedio

WITH 
  a1 
  	AS 
  (
	 SELECT	CONCAT(t.nombre, ' ', t.apellido) AS tutor
		,COUNT(*) AS alumnos_por_tutor
	 FROM	platzi.alumnos AS a
	 INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id 
	 GROUP BY tutor
	 ORDER BY alumnos_por_tutor DESC
  )
  
SELECT avg (a1.alumnos_por_tutor)
FROM a1

SELECT MIN(nombre)
FROM platzi.alumnos;

SELECT tutor_id, MIN(nombre)
FROM platzi.alumnos
GROUP BY tutor_id
ORDER BY tutor_id;

Solución Reto anterior:

SELECT nombre
FROM platzi.alumnos
ORDER BY nombre;
SELECT tutor_id, MIN (nombre)
FROM platzi.alumnos
GROUP BY tutor_id
ORDER BY tutor_id;

Solución al reto de la clase.

PD: El promedio de estudiantes por tutor me dió 33.33 para cada tutor, no sé si el dato es correcto. Me dejan saber en los comentarios

SELECT
	tutor,
	alumnos_por_tutor,
	(SELECT AVG(alumnos_por_tutor) FROM (
		SELECT
			CONCAT(t.nombre, ' ', t.apellido) AS tutor,
			COUNT(a.tutor_id) AS alumnos_por_tutor
		FROM platzi.alumnos AS a
			INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id	
		GROUP BY tutor
	) AS subquery) AS avg_alumnos
FROM (
	SELECT
		CONCAT(t.nombre, ' ', t.apellido) AS tutor,
		COUNT(*) AS alumnos_por_tutor
	FROM platzi.alumnos AS a
		INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id	
	GROUP BY tutor
	ORDER BY alumnos_por_tutor DESC
	) AS subquery

Me siento toda hacker 😛

SELECT AVG(l.alumnos_por_tutor) AS avg_alumnos_por_tutor
FROM (SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor,
	   COUNT(*) AS alumnos_por_tutor
FROM   platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t 
	ON a.tutor_id = t.id
GROUP BY tutor
ORDER BY alumnos_por_tutor DESC) AS l;

para que se viera mas limpio propuse esta solución

WITH alumnos_por_tutor as 
(
SELECT	CONCAT(t.nombre, ' ', t.apellido) AS tutor,
		COUNT(*) AS alumnos_por_tutor
FROM	platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
GROUP BY tutor
ORDER BY alumnos_por_tutor DESC
)
SELECT AVG(alumnos_por_tutor) FROM alumnos_por_tutor

Curiosamente el operador / en Postgresql se toma más como división modular que división normal. Toca usar casts y un poco de matemáticas (potenciación) para obtener el número sin necesidad de JOINs.

SELECT ROUND(COUNT(*) * (COUNT(DISTINCT(tutor_id))::numeric^(-1.0)),2)
FROM platzi.alumnos;

Un poco a mi manera pero que felicidad haberlo hecho.

SELECT CONCAT(b.nombre,' ',b.apellido) AS nombre_tutor,
       COUNT(*) as numero_alumnos
FROM platzi.alumnos a
INNER JOIN platzi.alumnos b
           ON a.tutor_id = b.id
GROUP BY nombre_tutor
ORDER BY numero_alumnos DESC
LIMIT 5;

Mi solucion:

SELECT AVG(total.alumnos_por_tutor)
FROM (
	SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor,
	COUNT(*) AS alumnos_por_tutor
FROM platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t 
	ON a.tutor_id = t.id
GROUP BY tutor
) as total 

Sobre el tema del MIN cuando es de tipo varchar no funciona tan bien como creemos
Ejemplo:

select min(nombre) from platzi.alumnos limit 1

Esto nos va a devolver el nombre ‘Abbey’ pero esto es incorrecto ya que existen nombres mas ‘chicos’

Para solucionar esto podemos hacer algo asi

select nombre from platzi.alumnos 
order by length(nombre) asc limit 1

Esto nos va a devolver ‘Cy’ ya que ordenamos los nombres por caracter

No era necesario unir la tabla con si misma

select avg(tutor.count)
from(
	select tutor_id, count(*) from platzi.alumnos group by tutor_id
	)
	as tutor;

la solucione de esta forma

SELECT min(nombre),max(tutor_id)
FROM platzi.alumnos
limit 1



select min(nombre),tutor_id
FROM platzi.alumnos
group by(tutor_id)

RETO
Obtener el promedio general de la cantidad de alumnos por tutor.


  • Solución 1:
SELECT ROUND(AVG(alumnos_por_tutor),2) promedio_general
FROM (
SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor, COUNT(*) AS alumnos_por_tutor
FROM platzi.alumnos a
INNER JOIN platzi.alumnos t ON a.tutor_id = t.id
GROUP BY tutor
ORDER BY alumnos_por_tutor DESC
) tutor_alumnos;

ADICIONAL 1
Obtener el porcentaje de la cantidad de alumnos por cada tutor.


  • Solución:
SELECT tutor, alumnos_por_tutor, ROUND((alumnos_por_tutor::decimal(18,2)/total_alumnos)*100,2) porcentaje
FROM (
	SELECT 
		CONCAT(t.nombre, ' ', t.apellido) AS tutor, 
		COUNT(*) alumnos_por_tutor,
		(SELECT COUNT(*) FROM platzi.alumnos) total_alumnos
	FROM platzi.alumnos a
	INNER JOIN platzi.alumnos t ON a.tutor_id = t.id
	GROUP BY tutor
) t1;

ADICIONAL 2
Seleccionar la cantidad de alumnos y cuántas carreras enseña por cada tutor.


  • Solución:
SELECT  
	t.id cod_tutor,
	CONCAT(t.nombre, ' ', t.apellido) AS tutor, 
	COUNT(*) alumnos_por_tutor,
	COUNT(DISTINCT a.carrera_id) carreras_por_tutor
FROM platzi.alumnos a
INNER JOIN platzi.alumnos t ON a.tutor_id = t.id
GROUP BY cod_tutor, tutor;

Tambien para concatener en postgre existe la funcion concat_ws

concat_WS(' ',a.nombre,a.apellido) AS ALUMNO

eso ayuda a que no quede ese espacio al final que deja concat cuando solo habia un nombre

el reto pero desde el punto de vista del promedio de alumnos por carrera.

--Promedio de Alumnos que tiene cada carrera
SELECT AVG(Curso_Alumno) AS Promedio_Alumnos_Cursos
FROM(
	SELECT c.carrera_id AS Curso, COUNT(*) AS Curso_Alumno
	FROM platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS c ON a.carrera_id = c.id
	GROUP BY Curso, a.carrera_id
	ORDER BY Curso_Alumno DESC
) AS Promedio


El Alias del SUb-Query Tu_Es significa (Tutor - Estudiantes)

Solución del reto

-- promedio de alumnos por tutor
select ROUND(avg(alumno_por_tutor))
from(
	select concat(t.nombre,' ',t.apellido) as tutor,
		count(*) as alumno_por_tutor
	from platzi.alumnos as a
		inner join platzi.alumnos as t on a.tutor_id = t.id
group by tutor
) as asignados;

Respuesta a la practica

select min(nombre) from platzi.alumnos

select tutor_id, min(nombre) from platzi.alumnos
group by tutor_id
order by tutor_id

reto:

SELECT AVG(cantidad_alumnos) AS promedio_alumnos_por_tutor
FROM (
	SELECT
		CONCAT (t.nombre,' ', t.apellido) AS tutor,
		COUNT (*) AS cantidad_alumnos
	FROM platzi.alumnos a
	INNER JOIN platzi.alumnos t ON a.tutor_id= t.id
	GROUP BY tutor
) AS tutor_cantidad_alumnos

Mi reto:

select tutor_id, min(nombre)
from platzi.alumnos
group by tutor_id
order by tutor_id desc

Si quieres saber el numero de estudiantes por tutor, con un query rápido lo puedes hacer:

SELECT tutor_id, count(*) as alumnos from platzi.alumnos
groupby tutor_id
orderby alumnos desc;

Pero ahora, queremos saber quienes son estos tutor_ids, que por cierto, también son alumnos. Se trabaja sobre el mismo query, haciendo un **join ** a la misma tabla, alumnos:

SELECT a.tutor_id, count(*) as alumnos from platzi.alumnos as a
JOIN platzi.alumnos as b
ON a.tutor_id = b.id
groupby a.tutor_id
orderby alumnos desc;

Bien, como ya está relacionado, todo tutor_id en a hace referencia a un alumno_id de la tabla b, entonces solo nos traemos el nombre del alumno en b que será tutor en la tabla a

SELECT b.nombre as tutor, count(*) as alumnos FROM platzi.alumnos as a
JOIN platzi.alumnos as b
ON a.tutor_id = b.id
GROUPby tutor
ORDERby alumnos desc;
SELECT AVG(alumnos)
FROM (SELECT
        concat(c.nombre, ' ', c.apellido) as tutor,
        count(*) alumnos
    FROM platzi.alumnos as a
    join platzi.alumnos as c
    on a.tutor_id = c.id
    GROUP by tutor
    order by alumnos desc
) as averaging;

Reto: La segunda forma es más rápida

/*1RA FORMA: Promedio de alumnos por tutor*/
SELECT AVG(alumnos_por_tutor) AS promedio_alumnos_por_tutor
FROM (SELECT CONCAT(t.nombre,' ',t.apellido) AS tutor,COUNT(*) AS alumnos_por_tutor
	 FROM platzi.alumnos AS a
	 INNER JOIN platzi.alumnos AS t
	 ON a.tutor_id = t.id
	 GROUP BY tutor) AS alumnos_tutor
	 
/*2DA FORMA: Promedio de alumnos por tutor*/
SELECT (SUM(alumnos_por_tutor)/ COUNT(tutor)) AS promedio_alumnos_por_tutor
FROM (SELECT CONCAT(t.nombre,' ',t.apellido) AS tutor,COUNT(*) AS alumnos_por_tutor
	 FROM platzi.alumnos AS a
	 INNER JOIN platzi.alumnos AS t
	 ON a.tutor_id = t.id
	 GROUP BY tutor) AS alumnos_tutor

Mi solución del reto:

SELECT AVG(t.alumnos_por_tutor) AS promedio_alumnos_por_tutor
FROM (
	SELECT CONCAT(t.nombre,' ',t.apellido) AS tutor,
		COUNT(*) AS alumnos_por_tutor
	FROM platzi.alumnos a
	INNER JOIN platzi.alumnos t ON a.tutor_id=t.id
	GROUP BY tutor
	ORDER BY tutor
) AS t

Una solución al reto:

SELECT AVG(promedio_alumnos_por_tutor) AS promedio_alumnos_tutor
FROM (SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor,
		COUNT(*) AS promedio_alumnos_por_tutor
FROM platzi.alumnos AS a
	INNER JOIN platzi.alumnos as t ON a.tutor_id = t.id
GROUP BY tutor
ORDER BY promedio_alumnos_por_tutor
) AS promedio;
SELECT AVG(alumnos_por_tutor) AS promedio_alumnos
FROM(
     SELECT CONCAT(t.nombre,' ', t.apellido) AS tutor, COUNT(*) AS alumnos_por_tutor
     FROM platzi.alumnos AS a
         INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
     GROUP BY tutor
     ORDER BY alumnos_por_tutor DESC) AS alumnos_grupo;
SELECT tutor_id, MIN(nombre)
FROM platzi.alumnos
GROUP BY tutor_id;

Esta fue la solución al reto propuesto y un reto personal adicional:

/* RETO: Sacar el promedio de alumnos por tutor */

SELECT AVG(test)
FROM(
	SELECT CONCAT (al.nombre,' ', al.apellido) AS tutor,  COUNT(*) AS test
	FROM platzi.alumnos as al
	INNER JOIN platzi.alumnos as ab
	ON al.id =ab.tutor_id
	GROUP BY tutor
	
)AS test

/*Reto Personal: Promedio de tutorores por carrera*/

SELECT carrera, AVG(cantidad_tutorias_carrera) AS t
FROM (
	SELECT CONCAT(a1.carrera_id) AS carrera, COUNT(*) AS cantidad_tutorias_carrera
	FROM platzi.alumnos AS a1
	INNER JOIN platzi.alumnos AS a2
	ON a1.id = a2.tutor_id
	GROUP BY carrera
	ORDER BY carrera ASC
) AS calculo
GROUP BY carrera
ORDER BY t ASC;

Podemos agregarle la carrera de la tutoría de la siguiente manera:

FROM(
SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor,
	COUNT(*) AS tutorias_por_carrera, c.carrera
FROM platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t
	ON a.tutor_id = t.id-----relacion del id del alumno con el id del tutor, un SELF JOIN
	INNER JOIN platzi.carreras AS c
	ON c.id = t.tutor_id
--WHERE c.vigente = true
GROUP BY tutor, c.carrera
ORDER BY tutorias_por_carrera DESC;

Solución al reto:

  1. El mínimo del nombre en toda la tabla:
SELECT nombre
FROM platzi.alumnos
GROUP BY nombre
ORDER BY nombre
LIMIT 1;
  1. EL mínimo del nombre por tutor_id:
SELECT MIN(nombre), tutor_id
FROM platzi.alumnos
GROUP BY tutor_id
ORDER BY tutor_id;
from(SELECT count(*) as alumnos_por_tutor 
  FROM alumnos as a_
      INNER join alumnos as t_
      on a_.tutor_id = t_.id
  GROUP by t_.id)as est_por_tut;´´´

El reto del promedio de alumnos:

SELECT AVG(alumnos_por_tutor) as promedio_de_alumnos
FROM (
SELECT 	CONCAT(t.nombre, ' ', t.apellido) AS tutor,
		COUNT(*) AS alumnos_por_tutor
FROM platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
GROUP BY tutor) AS numero_alumnos_tutor;

Desafío:

-- Reto: promedio general de alumnos por tutor

SELECT AVG(alumnos_por_tutor)
FROM (
	SELECT CONCAT( t.nombre, ' ', t.apellido) AS tutor,
			COUNT(*) AS alumnos_por_tutor
	FROM platzi.alumnos AS a
		INNER JOIN platzi.alumnos AS T 
		ON a.tutor_id = t.id
	GROUP BY tutor
	ORDER BY alumnos_por_tutor DESC
) AS tabla_alumnos_por_tutor;

Solución al reto de la clase pasada

-- el mínimo por tabla
select *
from platzi.alumnos
order by nombre asc
limit 1;

-- el mínimo por tutor id
select tutor_id, min(nombre)
from platzi.alumnos
group by tutor_id
order by tutor_id;
SELECT AVG(alumnos_por_tutor)
FROM(

SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor, COUNT(*)  AS alumnos_por_tutor
FROM platzi.alumnos AS a
inner join platzi.alumnos as t ON a.tutor_id=t.id
GROUP BY tutor
order by alumnos_por_tutor
	) AS promedio

Solución al reto:

SELECT AVG(alumnos_por_tutor) AS promedio_tutorias
FROM (
	SELECT CONCAT (t.nombre, ' ', t.apellido) AS tutor,
	COUNT(*) AS alumnos_por_tutor
	FROM platzi.alumnos AS a
	INNER JOIN platzi.alumnos AS t
		ON a.tutor_id = t.id
	GROUP BY tutor
	) AS promedio;

Reto de la clase, encontrar el promedio de alumnos por tutores

¿Cuántos alumnos tiene cada tutor?

Selfjoin y CONCAT para unir campos

Introducción a selfjoins, alumnos y tutores

Solucion de la tarea encontrar valores mínimos

Solución al reto:

SELECT AVG(alumnos_por_tutor) AS promedio_alumnos_por_tutor
FROM (
	SELECT  CONCAT(t.nombre,' ',t.apellido) AS tutor,
			COUNT(*) AS alumnos_por_tutor
	FROM platzi.alumnos AS a
		INNER JOIN platzi.alumnos AS t
		ON a.tutor_id = t.id
	GROUP BY tutor
	ORDER BY alumnos_por_tutor DESC
) AS tutor_alumnos;

Resultado:
33.33333333

Mi solución al reto, no se si sea muy deportivo pero fue como lo pensé:🧓🏽

SELECT COUNT(id) / COUNT(DISTINCT(tutor_id)) AS promedio_alumnosXtutor
FROM platzi.alumnos

Reto 7:

SELECT AVG(total_alumnos) AS promedio_alumnos_por_tutor
FROM (SELECT	CONCAT(t.nombre, ' ', t.apellido) AS tutor,
		COUNT(*) AS total_alumnos
FROM	platzi.alumnos AS a
	INNER JOIN  platzi.alumnos AS t ON a.tutor_id = t.id
GROUP BY tutor
ORDER BY total_alumnos DESC
) AS promedio;

RETO

Así quedó

-- El promedio de alumnos por tutor --
SELECT AVG(tutores.alumnos_por_tutor)
FROM (
	SELECT	CONCAT(t.nombre, ' ', t.apellido) AS tutor,
			COUNT(*) AS alumnos_por_tutor
	FROM	platzi.alumnos AS a
		INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
	GROUP BY tutor
	ORDER BY alumnos_por_tutor DESC
) AS tutores;

MI solución del reto

SELECT AVG(alumnos_por_tutor) as promedio
FROM (SELECT CONCAT(t.nombre, ' ', t.apellido) AS tutor,
			COUNT(*) AS alumnos_por_tutor
	FROM platzi.alumnos AS a
		INNER JOIN platzi.alumnos AS t ON a.tutor_id = t.id
	GROUP BY tutor 
	ORDER BY alumnos_por_tutor DESC
	) as tabled
SELECT COUNT (DISTINCT id) / COUNT (DISTINCT tutor_id)
FROM platzi.alumnos

Comparo mis respuestas para el reto de la clase anterior:
Primer reto

SELECT MIN(nombre)
FROM platzi.alumnos

Segundo reto

SELECT tutor_id, MIN(nombre)
FROM platzi.alumnos
GROUP BY 1

Reto #9

SELECT AVG(alumnos_por_tutor)
FROM (
SELECT	CONCAT(t.nombre,  ' ', t.apellido) AS tutor,
		COUNT(*) AS alumnos_por_tutor
FROM 	platzi.alumnos AS a
		INNER JOIN platzi.alumnos AS t
		ON a.tutor_id = t.id
GROUP BY tutor) AS tabla_almunos_por_tutor;