T-SQL GROUP BY: лучший способ включить другие сгруппированные столбцы
-
06-07-2019 - |
Вопрос
Я - пользователь MySQL, пытающийся перенести некоторые вещи на MS SQL Server.
Я присоединяюсь к нескольким таблицам и собираю некоторые столбцы с помощью GROUP BY.
Простым примером будут сотрудники и проекты:
select empID, fname, lname, title, dept, count(projectID)
from employees E left join projects P on E.empID = P.projLeader
group by empID
... это будет работать в MySQL, но MS SQL более строг и требует, чтобы все было либо включено в агрегатную функцию, либо являлось частью предложения GROUP BY.
Итак, конечно, в этом простом примере я предполагаю, что мог бы просто включить дополнительные столбцы в предложение group by. Но фактический запрос, с которым я имею дело, довольно сложен и включает в себя множество операций, выполняемых с некоторыми неагрегированными столбцами ... то есть, было бы ДЕЙСТВИТЕЛЬНО уродливо пытаться включить их все в предложение group by . р>
Так есть ли лучший способ сделать это?
Решение
Вы можете заставить его работать с чем-то вроде этих строк:
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
Таким образом, вы избегаете лишних групп по операциям и можете получать любые данные. Кроме того, у вас больше шансов эффективно использовать индексы в некоторых сценариях (если вы не возвращаете полную информацию), и их можно лучше сочетать с подкачкой страниц.
Другие советы
" было бы ДЕЙСТВИТЕЛЬНО уродливо пытаться включить их всех в группу по выражению. "
Да, это единственный способ сделать это * - просто скопируйте и вставьте неагрегированные столбцы в предложение group by, удалите псевдонимы, и это так же хорошо, как и получается ...
* вы можете обернуть его во вложенный SELECT, но это, вероятно, так же ужасно ...
MySQL необычен - и технически несовместим со стандартом SQL - позволяет вам пропускать элементы из предложения GROUP BY. В стандартном SQL каждый неагрегированный столбец в списке выбора должен быть полностью указан в предложении GROUP BY (либо по имени, либо по порядковому номеру, но это не рекомендуется).
(О, хотя MySQL необычен, хорошо, что он допускает сокращение.)
Вам не нужно присоединяться к подзапросу, так как нет необходимости создавать группы на основе empID из сотрудников - вы можете сделать это в поле projectLeader из проектов. Р>
С помощью внутреннего объединения (как я уже сказал) вы получите список сотрудников, у которых есть хотя бы один проект. Если вы хотите список всех сотрудников, просто измените его на левое присоединение
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
Подзапрос в предложении select также может быть подходящим. Это будет работать для данного примера, но не для реального сложного запроса, с которым вы имеете дело.
select
e.empID, fname, lname, title, dept
, (select count(*) from projects p where p.projLeader = e.empId) as projectCount
from
from employees E