SQL-tener VS donde


Tengo dos tablas:

1. Lecturers (LectID, Fname, Lname, degree).
2. Lecturers_Specialization (LectID, Expertise).

Quiero encontrar al profesor con la mayor especialización. Cuando intento esto, no está funcionando:

SELECT
  L.LectID,
  Fname,
  Lname
FROM Lecturers L,
     Lecturers_Specialization S
WHERE L.LectID = S.LectID
AND COUNT(S.Expertise) >= ALL (SELECT
  COUNT(Expertise)
FROM Lecturers_Specialization
GROUP BY LectID);

Pero cuando intento esto, funciona:

SELECT
  L.LectID,
  Fname,
  Lname
FROM Lecturers L,
     Lecturers_Specialization S
WHERE L.LectID = S.LectID
GROUP BY L.LectID,
         Fname,
         Lname
HAVING COUNT(S.Expertise) >= ALL (SELECT
  COUNT(Expertise)
FROM Lecturers_Specialization
GROUP BY LectID); 

¿Cuál es la razón? Gracias.

Author: Laxmi, 2012-02-13

7 answers

WHERE la cláusula introduce una condición en filas individuales; HAVING la cláusula introduce una condición en agregaciones, es decir, resultados de selección donde un solo resultado, como count, average, min, max o sum, se ha producido a partir de múltiples filas. Su consulta requiere un segundo tipo de condición (es decir, una condición en una agregación) por lo tanto HAVING funciona correctamente.

Como regla general, utilice WHERE antes de GROUP BY y HAVING después de GROUP BY. Es un lugar primitivo regla, pero es útil en más del 90% de los casos.

Mientras está en ello, es posible que desee volver a escribir su consulta utilizando la versión ANSI de la combinación:

SELECT  L.LectID, Fname, Lname
FROM Lecturers L
JOIN Lecturers_Specialization S ON L.LectID=S.LectID
GROUP BY L.LectID, Fname, Lname
HAVING COUNT(S.Expertise)>=ALL
(SELECT COUNT(Expertise) FROM Lecturers_Specialization GROUP BY LectID)

Esto eliminaría WHERE que se usó como una condición de unión theta .

 271
Author: dasblinkenlight,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-26 20:35:40

HAVING funciona con agregados. Dado que COUNT es una función aggregate, no se puede usar en una cláusula WHERE.

He aquí algunas lecturas de MSDN sobre funciones agregadas.

 33
Author: Daniel Mann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-12 22:19:10

Primero debemos conocer el orden de ejecución de las Cláusulas i. e FROM > WHERE > GROUP BY > HAVING > DISTINCT > SELECT > ORDER BY. Dado que la cláusula WHERE se ejecuta antes de la Cláusula GROUP BY los registros no se pueden filtrar aplicando WHERE a un GROUP BY registros aplicados.

"TENER es lo mismo que la cláusula WHERE pero se aplica en registros agrupados".

Primero la cláusula DONDE obtiene los registros basados en la condición luego la cláusula GROUP BY los agrupa en consecuencia y luego la cláusula HAVING obtiene los registros de grupo basados en la condición having.

 10
Author: Pardhu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-27 13:41:52
  1. La cláusula WHERE se puede usar con las instrucciones SELECT, INSERT y UPDATE, mientras que HAVING solo se puede usar con la instrucción SELECT.

  2. DONDE filtra las filas antes de la agregación (AGRUPAR POR), mientras que TENER grupos de filtro después de las agregaciones se realizan.

  3. La función Aggregate no se puede usar en la cláusula WHERE a menos que esté en una subconsulta contenida en la cláusula HAVING, mientras que las funciones aggregate se pueden usar en TENER clausula.

Fuente

 10
Author: Venkata Krishna Reddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-13 15:22:01

No se puede usar la cláusula where con funciones agregadas porque donde se obtienen registros sobre la base de la condición, se entra en la tabla registro por registro y luego se obtiene registro sobre la base de la condición que tenemos que dar. Así que esa vez no podemos dónde cláusula. Mientras que la cláusula having funciona en el conjunto de resultados que finalmente obtenemos después de ejecutar una consulta.

Consulta de ejemplo:

select empName, sum(Bonus) 
from employees 
order by empName 
having sum(Bonus) > 5000;

Esto almacenará el conjunto de resultados en una memoria temporal, luego la cláusula having realizará su trabajo. Así que podemos fácilmente utilice funciones agregadas aquí.

 8
Author: Akash5288,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-27 13:32:10

No vio un ejemplo de ambos en una consulta. Así que este ejemplo podría ayudar.

  /**
INTERNATIONAL_ORDERS - table of orders by company by location by day
companyId, country, city, total, date
**/

SELECT country, city, sum(total) totalCityOrders 
FROM INTERNATIONAL_ORDERS with (nolock)
WHERE companyId = 884501253109
GROUP BY country, city
HAVING country = 'MX'
ORDER BY sum(total) DESC

Esto filtra la tabla primero por el CompanyId, luego la agrupa (por país y ciudad) y adicionalmente la filtra hasta solo agregaciones de ciudades de México. El CompanyId no era necesario en la agregación, pero pudimos usar WHERE para filtrar solo las filas que queríamos antes de usar GROUP BY.

 6
Author: Nhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-27 23:15:07

1. Podemos usar la función aggregate con tener cláusula no por DONDE cláusula e. g. min, max, avg.

2. La cláusula WHERE elimina el registro tupla por tupla La cláusula HAVING elimina todo el grupo de la colección de group

La mayor parte de TENER se usa cuando tiene grupos de datos y DÓNDE se usa cuando tiene datos en filas.

 2
Author: Mihir Trivedi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-29 15:51:16