Domanda

Sono un utente MySQL che sta provando a trasferire alcune cose su MS SQL Server.

Sto unendo un paio di tabelle e aggregando alcune delle colonne tramite GROUP BY.

Un semplice esempio potrebbe essere dipendenti e progetti:

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

... funzionerebbe in MySQL, ma MS SQL è più rigoroso e richiede che tutto sia racchiuso in una funzione aggregata o faccia parte della clausola GROUP BY.

Quindi, ovviamente, in questo semplice esempio, suppongo che potrei semplicemente includere le colonne extra nella clausola group by. Ma la query effettiva con cui ho a che fare è piuttosto complicata e include un sacco di operazioni eseguite su alcune delle colonne non aggregate ... vale a dire, sarebbe davvero brutto provare a includerle tutte nel gruppo in base alla clausola .

Quindi c'è un modo migliore per farlo?

È stato utile?

Soluzione

Puoi farlo funzionare con qualcosa attorno a queste righe:

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

In questo modo si evita il gruppo aggiuntivo per operazioni e si possono ottenere tutti i dati desiderati. Inoltre hai maggiori possibilità di fare buon uso degli indici in alcuni scenari (se non stai restituendo le informazioni complete) e puoi combinarli meglio con il paging.

Altri suggerimenti

" Sarebbe MOLTO brutto provare a includerli tutti nel gruppo per clausola. "

Sì - questo è l'unico modo per farlo * - basta copiare e incollare le colonne non aggregate nel gruppo per clausola, rimuovere gli alias ed è bello come si arriva ...

* potresti avvolgerlo in un SELECT nidificato ma probabilmente è altrettanto brutto ...

MySQL è insolito - e tecnicamente non conforme allo standard SQL - nel consentire di omettere elementi dalla clausola GROUP BY. In SQL standard, ogni colonna non aggregata nell'elenco di selezione deve essere elencata per intero nella clausola GROUP BY (per nome o per numero ordinale, ma che è obsoleta).

(Oh, sebbene MySQL sia insolito, è bello che consenta la scorciatoia.)

Non è necessario partecipare alla sottoquery in quanto non è necessario creare un gruppo in base a empID dei dipendenti: è possibile farlo nel campo projectLeader dai progetti.

Con il join interno (come ho scritto) otterrai l'elenco dei dipendenti che hanno almeno un progetto. Se vuoi un elenco di tutti i dipendenti, basta cambiarlo in join sinistro

  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

Potrebbe anche essere adatta una sottoquery nella clausola select. Funzionerebbe per l'esempio fornito ma potrebbe non essere per la query complicata che stai affrontando.

select
        e.empID, fname, lname, title, dept
        , (select count(*) from projects p where p.projLeader = e.empId) as projectCount
from
   from employees E
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top