2012-02-12 18 views
127

que tienen dos tipos de tabla:SQL - Vista VS donde

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

Quiero encontrar el profesor con los más 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.

+2

Puede aclarar qué versión de SQL está utilizando (MySQL, MS SQL, PostgreSQL, Oracle, etc.). Además, cuando dices "no funciona", ¿te refieres a que los resultados no son los esperados, o que hay un error de compilación/análisis? – jklemmack

+1

¿Por qué usa ALL en lugar de MAX ?. ¿Hay alguna ventaja? – skan

Respuesta

237

WHERE cláusula introduce una condición en filas individuales; La cláusula HAVING introduce una condición en las agregaciones , es decir, los resultados de la selección donde un único resultado, como recuento, promedio, mínimo, máximo o suma, se ha producido a partir de filas múltiples. 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, use WHERE antes de GROUP BY y HAVING después de GROUP BY. Es una regla bastante primitiva, pero es útil en más del 90% de los casos.

Mientras estás en ello, es posible que desee volver a escribir la consulta utilizando la versión ANSI de la unió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 utilizó como theta condición de combinación.

31

HAVING opera en los agregados. Como COUNT es una función agregada, no puede usarla en una cláusula WHERE.

Here's algunas lecturas de MSDN en funciones agregadas.

8

No se puede usar la cláusula where con funciones agregadas porque cuando busca registros en función de la condición, va al registro de la tabla por registro y luego obtiene el registro en función de la condición que le hemos dado. Entonces, ese momento no podemos donde la cláusula. Si bien tener cláusula funciona en el conjunto de resultados que finalmente obtenemos después de ejecutar una consulta.

Ejemplo de consulta:

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

Esto almacenará el conjunto de resultados en una memoria temporal, y luego tener la cláusula llevará a cabo su trabajo. Entonces, podemos usar fácilmente las funciones agregadas aquí.

+1

Creo que no podemos usar la cláusula HAVING sin la cláusula GROUP BY. Posición de cláusula HAVING - SELECCIONAR -> DESDE -> DÓNDE -> GRUPO POR -> TENIENDO -> ORDEN POR – Ronnie

8
  1. cláusula WHERE se puede utilizar con SELECT, INSERT y UPDATE, así como HAVING sólo se puede utilizar con instrucción SELECT.

  2. WHERE filtra las filas antes de la agregación (GROUP BY), mientras que TENIENDO grupos de filtros después de las agregaciones.

  3. La función de agregado 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 agregadas se pueden usar en la cláusula HAVING.

Source

2

1. Podemos utilizar la función de agregado con la cláusula HAVING no por la cláusula WHERE, por ejemplo, mínimo máximo promedio.

2. cláusula WHERE elimina la tupla disco de tupla cláusula HAVING elimina grupo entero de la colección del grupo

Mayormente se utiliza tiene cuando tienen grupos de datos y donde se utiliza cuando se tiene datos en filas .

4

No vi un ejemplo de ambos en una consulta. Entonces 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 por primera vez por el CompanyID, a continuación, los grupos que (según el país y ciudad) y, además, los filtros se reduce a sólo agregaciones de la ciudad de México. La empresaId no era necesaria en la agregación, pero pudimos usar DONDE filtrar solo las filas que queríamos antes de usar GROUP BY.

6

Primero debemos saber el orden de ejecución de las cláusulas, es decir, DESDE> DÓNDE> AGRUPAR> MOSTRAR> DISTINCT> SELECCIONAR> PEDIR POR. Desde DONDE Cláusula es ejecutado antes GRUPO POR cláusula los registros no se pueden filtrar mediante la aplicación de DONDE a un grupo POR registros aplicada.

"HAVING es igual que la cláusula WHERE pero se aplica en los registros agrupados".

primero la DONDE cláusula obtiene los registros en función de la condición a continuación, los GROUP BY grupos cláusula en consecuencia y luego la cláusula HAVING Obtiene los registros de grupo en base a la que tiene condiciones.