Estoy luchando con una consulta SQL,
Consulta:
Quiero encontrar una lista de hospitales con un recuento de dentistas (is_denitist=true) y todos los médicos (incluidos los dentistas) que tengan ingresos mensuales > 100 000
Tengo 2 tablas Hospitales y Doctores con el siguiente esquema,
------------- | Hospital | |-----------| | id | name | |-----------| --------------------------------------------------------- | Doctor | |-------------------------------------------------------- | id | name | monthly_income | is_dentist | hospital_id | |--------------------------------------------------------
La consulta que se me ocurrió es,
select h.name, count(d.is_dentist), sum(d.monthly_income) from Hospital h inner join Doctor d on h.id = d.hospital_id where d.monthly_income > 100000 and d.is_dentist=true group by h.name;
Si soy dentista y tengo un ingreso inferior a 100 000, entonces el hospital aún debe contarme como dentista.
Pero la advertencia en la consulta anterior es que filtra a todos los médicos que tienen ingresos mensuales superiores a 100 000 y son dentistas. Quiero un conteo independiente de estas condiciones como predicados sobre cada columna de conteo(). ¿Cómo podemos lograr esto en una sola consulta?
Puedes hacer agregación condicional.
Dado que is_dentist
( 1
) contiene valores 0
, puede simplemente sum()
esta columna para contar cuántos médicos pertenecen al grupo.
Por otro lado, puede usar otra sum()
para contar cuántos médicos tienen ingresos por encima del umbral.
select h.name, sum(d.is_dentist) no_dentists, sum(d.monthly_income > 100000) no_doctors_above_100000_income from Hospital h inner join Doctor d on h.id = d.hospital_id group by h.name;
Tiene dos condiciones independientes (monthly_income > 100000 y is_dentist=true), lo que significa que hay dos conjuntos de datos diferentes. No se pueden utilizar dos conjuntos de datos diferentes en la misma consulta de grupo. Entonces necesitas dividirlo en dos subconsultas. Puede verificar la siguiente consulta si el resultado es el que deseaba:
select temp3.name, temp1.dentist_count, temp2.income_count from (select d1.hospital_id, count(*) as dentist_count from Doctor d1 where d1.monthly_income>100000 group by d1.hospital_id) as temp1 join (select d2.hospital_id, count(*) as income_count from Doctor d2 where d2.is_dentist=true group by d2.hospital_id) as temp2 on temp1.hospital_id=temp2.hospital_id join (select h.id, h.name from Hospital h) as temp3 on temp2.hospital_id=temp3.id;