2009-03-09 5 views
10

Soy un usuario de MySQL que está tratando de transferir algunas cosas a MS SQL Server.GRUPO T-SQL POR: Mejor manera de incluir otras columnas agrupadas

Estoy uniendo un par de tablas y agregando algunas de las columnas a través de GROUP BY.

Un ejemplo sencillo sería empleados y proyectos:

select empID, fname, lname, title, dept, count(projectID) 
from employees E left join projects P on E.empID = P.projLeader 
group by empID 

... que trabajarían en MySQL, MS SQL, pero es más estricta y requiere que todo está bien encerrado en una función de agregado o es parte de la Cláusula GROUP BY.

Así que, por supuesto, en este sencillo ejemplo, supongo que podría incluir las columnas adicionales en la cláusula group by. Pero la consulta real con la que estoy tratando es bastante complicada e incluye un conjunto de operaciones realizadas en algunas de las columnas no agregadas ... es decir, se volvería realmente feo intentar incluirlas todas en la cláusula group by .

¿Hay alguna forma mejor de hacerlo?

+0

@ Dan, por favor, eche un vistazo a mi respuesta, que le ahorrará algunos problemas en el camino ... – eglasius

Respuesta

15

Puede conseguir que funcione con algo en torno a estas líneas:

select e.empID, fname, lname, title, dept, projectIDCount 
from 
(
    select empID, count(projectID) as projectIDCount 
    from employees E left join projects P on E.empID = P.projLeader 
    group by empID 
) idList 
inner join employees e on idList.empID = e.empID 

esta manera se evita la grupo extra por operaciones, y puede obtener cualquier información que desee. También tiene una mejor oportunidad de hacer un buen uso de los índices en algunos escenarios (si no está devolviendo la información completa), y se puede combinar mejor con paginación.

+0

Sí, tuvieron que actualizar la sintaxis que no me di cuenta que había un recuento en el selecto lista. También se agregó cierta información sobre por qué hacerlo de esta manera. – eglasius

4

"se volvería realmente feo intentar incluirlos todos en la cláusula group by".

Sí - esa es la única manera de hacerlo * - sólo debes copiar y pegar las columnas no agregados en la cláusula GROUP BY, eliminar los alias y eso es tan bueno como se pone ...

* usted podría envuélvalo en un SELECT anidado, pero probablemente sea igual de feo ...

2

MySQL es inusual, y técnicamente no cumple con el estándar SQL, al permitirle omitir elementos de la cláusula GROUP BY. En SQL estándar, cada columna no agregada en la lista de selección se debe enumerar por completo en la cláusula GROUP BY (por nombre o por número ordinal, pero que está en desuso).

(Oh, aunque MySQL es inusual, es agradable que permite que la taquigrafía.)

1

No necesita unirse a la subconsulta, ya que no es necesario agrupar según empID de los empleados: puede hacerlo en el campo projectLeader de los proyectos.

Con la unión interna (como lo mencioné) obtendrá la lista de empleados que tienen al menos un proyecto. Si desea una lista de todos los empleados simplemente cámbiela a la combinación izquierda

select e.empID, e.fname, e.lname, e.title, e.dept, p.projectIDCount 
    from employees e 
    inner join (select projLeader, count(*) as projectIDCount 
        from projects 
       group by projLeader 
      ) p on p.projLeader = e.empID 
0

Una subconsulta en la cláusula de selección también podría ser adecuada. Funcionaría para el ejemplo dado, pero podría no funcionar para la consulta complicada real con la que está tratando.

select 
     e.empID, fname, lname, title, dept 
     , (select count(*) from projects p where p.projLeader = e.empId) as projectCount 
from 
    from employees E 
Cuestiones relacionadas