Как использовать GROUP BY с SELF JOIN? - PullRequest
1 голос
/ 05 октября 2011

У меня есть таблица персоны, в которой одновременно хранятся персона и его менеджер.
Я использую SELF JOIN для выбора электронной почты менеджера, но получаю много дубликатов.

http://imageshack.us/photo/my-images/3/withoutgroupby.png

How могу ли я использовать GROUP BY с моим запросом

SELECT              P.prs_id AS 'Employee_id', M.prs_id AS 'Manager_id', M.prs_email AS 'Manager_email'
FROM                qrd_prs_person AS P
LEFT OUTER JOIN     qrd_prs_person AS M  
ON                  P.prs_manager_number = M.prs_number

GROUP BY M.prs_id

Если я добавлю эту строку в конце моего запроса, чтобы сгруппировать поManager_id, я получаю эту ошибку

Столбец 'qrd_prs_person.prs_id' недопустим в списке выбора, поскольку он не содержится ни в статистической функции, ни в предложении GROUP BY.

Ответы [ 5 ]

3 голосов
/ 05 октября 2011

Я не совсем уверен, чего вы пытаетесь достичь?

Если вам нужен запрос, который возвращает по одной строке на сотрудника с двумя необязательными столбцами, содержащими информацию менеджера, то ваш исходный запросправильно (без группы по).Соотношение «многие к одному», вы начинаете со строки «много», каждая из которых имеет одну (необязательную) «единицу», поэтому нет необходимости группировать по.

Это однакопри условии, что ваши данные верны и что prs_number фактически уникален для каждого сотрудника.Если у вас есть два или более менеджеров, совместно использующих номер prs_number, вы в конечном итоге получите людей, имеющих несколько менеджеров.

Делая это внешнее объединение, вы также возвращаете людей без менеджера (т. Е. В верхней части пищевой цепи:)), это было ваше намерение?

РЕДАКТИРОВАТЬ

Если вы хотите, чтобы возвращались только менеджеры, то вы не можете оставить первый столбец (P.prs_id) и получитьодин ряд на менеджера.Если вам нужен список людей, которые управляют одним или несколькими людьми, это поможет:

SELECT              M.prs_id AS 'Manager_id', M.prs_email AS 'Manager_email'
FROM                qrd_prs_person AS P
INNER JOIN          qrd_prs_person AS M  
ON                  P.prs_manager_number = M.prs_number
GROUP BY            M.prs_id, M.prs_email
1 голос
/ 05 октября 2011

Почему вы хотите группировать, поскольку я не вижу Мин, Макс, Сумма или что-либо, что требует группировки? Может быть, order by будет достаточно? В любом случае, если вы GROUP BY, в предложении GROUP BY присутствует любой столбец, который не SUMmed или MINed и т. Д. ДОЛЖЕН .

0 голосов
/ 05 октября 2011

Проблема в том, что когда вы делаете group by, внезапно у вас появляется много возможных ответов для содержимого P.prs_id AS 'Employee_id' в предложении select.(По одному на каждого из сотрудников менеджера.) SQL Sever хочет точно знать, что вы хотите туда сделать, поэтому настаивает на том, чтобы вы предоставили какой-то способ суммирования всех значений этого в одно значение.

Возможно, вы хотите получить количество сотрудников, поэтому просто замените его на COUNT(P.prs_id) AS 'Employee_count'.

Вам также необходимо добавить M.prs_email в вашу группу по предложению.

0 голосов
/ 05 октября 2011

Если бы вы использовали MySQL, он бы просто взял одно из значений M.prs_id из группы. Но эти значения могут быть разными внутри группы, поэтому не имеет смысла просто выбирать случайное из них. Вот почему SQL Server жалуется.

Я думаю, вы просто неправильно поняли, как работает GROUP BY. Что именно вы пытаетесь достичь с помощью этого запроса?

0 голосов
/ 05 октября 2011

Все ваши столбцы в операторе select должны быть сгруппированы или иметь функцию агрегирования, вы можете попробовать добавить MAX (qrd_prs_person.prs_id) и посмотреть, работает ли он. Должно помочь вам: -)

Также вам нужно будет добавить часть идентификатора электронной почты в группу за частью, иначе используйте MAX () Ваш запрос должен быть

SELECT  MAX(P.prs_id) AS 'Employee_id', 
        M.prs_id AS 'Manager_id', 
        M.prs_email AS 'Manager_email'
FROM                
    qrd_prs_person AS P
    LEFT OUTER JOIN     
        qrd_prs_person AS M  ONP.prs_manager_number = M.prs_number
GROUP BY 
    M.prs_id, M.prs_email
...