T-SQL GROUP BY: лучший способ включить другие сгруппированные столбцы

StackOverflow https://stackoverflow.com/questions/626788

Вопрос

Я - пользователь 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top