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