Pregunta

Soy un usuario de MySQL que intenta transferir algunas cosas a MS SQL Server.

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

Un ejemplo simple 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

... eso funcionaría en MySQL, pero MS SQL es más estricto y requiere que todo esté encerrado en una función agregada o sea parte de la cláusula GROUP BY.

Entonces, por supuesto, en este simple ejemplo, supongo que podría incluir las columnas adicionales en el grupo por cláusula. Pero la consulta real con la que estoy tratando es bastante complicada e incluye un montón de operaciones realizadas en algunas de las columnas no agregadas ... es decir, sería REALMENTE feo tratar de incluirlas todas en el grupo por cláusula .

Entonces, ¿hay una mejor manera de hacer esto?

¿Fue útil?

Solución

Puede hacer que funcione con algo alrededor de 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

De esta manera evita el grupo adicional por operaciones, y puede obtener los datos 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 puede combinarse mejor con la paginación.

Otros consejos

" sería REALMENTE feo tratar de incluirlos a todos en el grupo por cláusula. "

Sí, esa es la única forma de hacerlo *: simplemente copie y pegue las columnas no agregadas en el grupo por cláusula, elimine los alias y eso es lo mejor que puede ...

* podría envolverlo en un SELECT anidado, pero probablemente sea igual de feo ...

MySQL es inusual, y técnicamente no cumple con el estándar SQL, ya que le permite omitir elementos de la cláusula GROUP BY. En el SQL estándar, cada columna no agregada en la lista de selección debe estar lista en su totalidad en la cláusula GROUP BY (ya sea por nombre o por número ordinal, pero está en desuso).

(Oh, aunque MySQL es inusual, es bueno que permita la taquigrafía).

No es necesario unirse a la subconsulta, ya que no es necesario hacer un grupo basado en el empID de los empleados; puede hacerlo en el campo projectLeader de los proyectos.

Con la unión interna (como puse) obtendrá una lista de empleados que tienen al menos un proyecto. Si desea una lista de todos los empleados, simplemente cámbiela para unirse a la 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

Una subconsulta en la cláusula select también podría ser adecuada. Funcionaría para el ejemplo dado, pero puede que no 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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top