2014-10-15 1 views
0

Предположим, у меня есть таблица Employee и таблица отдела. У каждого сотрудника есть один отдел.SQL-фильтрация по совокупным функциям

Теперь предположим, что я хочу видеть все отделы --along с сотрудниками этих departments--, которые имеют ровно 1 сотрудника.

Скажем, моя база данных выглядит так.

Сотрудник

EmployeeId | EmployeeName | DepartmentId 
-------------------------------------------- 
1   | A Doe   | 1 
-------------------------------------------- 
2   | B Doe   | 1 
-------------------------------------------- 
3   | C Doe   | 1 
-------------------------------------------- 
4   | D Doe   | 1 
-------------------------------------------- 
5   | E Doe   | 2 
-------------------------------------------- 

Департамент

DepartmentId | DepartmentName 
------------------------------------------ 
1    | Sales 
------------------------------------------      
2    | HR 
------------------------------------------ 

То, что я хочу видеть это следующие результаты:

DepartmentName | EmployeeId | EmployeeName | EmployeeId_COUNT 
------------------------------------------------------------------ 
HR    | NULL  | NULL   | 1 
------------------------------------------------------------------ 
HR    | 5   | E Doe   | 1 
------------------------------------------------------------------ 

Очевидно, что это может быть сделано с несколькими, SEPA .

Но, Кто-нибудь знает способ решить эту проблему одним запросом?

Моей первоначальная идея состояла в том, чтобы сделать что-то простое, как этот

SELECT 
     d.DepartmentName 'Department' 
     , e.EmployeeId 'EmployeeId' 
     , e.EmployeeName 
     , COUNT(e.EmployeeId) 'EmployeeId_COUNT' 

FROM Employee e 
     LEFT JOIN Department d ON d.DepartmentId = e.DepartmentId 

GROUP BY GROUPING SETS ( 
       (d.DepartmentName), 
       (d.DepartmentName, e.EmployeeId, e.EmployeeName)) 
HAVING COUNT(e.EmployeeId) IN (1) 

Но это не работает, так как каждый ряд, который не сгруппированные строки (и некоторые сгруппированные строки, а) имеет EmployeeID Количество 1.

Таким образом, результаты будут выглядеть следующим образом:

DepartmentName | EmployeeId | EmployeeName | EmployeeId_COUNT 
------------------------------------------------------------------ 
HR    | NULL  | NULL   | 1 
------------------------------------------------------------------ 
HR    | 5   | E Doe   | 1 
------------------------------------------------------------------ 
Sales   | 1   | A Doe   | 1 
------------------------------------------------------------------ 
Sales   | 2   | B Doe   | 1 
------------------------------------------------------------------ 
Sales   | 3   | C Doe   | 1 
------------------------------------------------------------------ 
Sales   | 4   | D Doe   | 1 
------------------------------------------------------------------ 

Это не то, что я хочу, у всех.

Мое идеальное решение просто (без сложных внутренних запросов, UNIONs или INTERSECTs) и легко обобщается на аналогичные проблемы (SUM, MAX, MIN и т. Д., А также другие столбцы в более сложных запросах).

Я также должен отметить, что Я делаю это в T-SQL 2012, поэтому любые специальные функции или команды, которые могут быть полезны, являются честной игрой.

+0

Можете ли вы еще раз взглянуть на ваши данные образца и желаемые результаты? Они не то, что вы, кажется, описываете. Почему HR должен быть в результатах с NULL для сотрудника? Почему E Doe в HR в результатах, но в Sales в ваших образцовых данных? –

+0

@TabAlleman HR с NULL для сотрудника находится в результатах моего неправильного запроса, потому что я использовал команду GROUPING SETS. См. Http://msdn.microsoft.com/en-us/library/ms177673(v=sql.110).aspx Это в моих предполагаемых результатах просто потому, что я определил их таким образом (удобно решать особая проблема, над которой я работаю). Другие проблемы - это ошибки, и я исправлю их в ближайшее время. –

ответ

1

Вы можете использовать COUNT() с OVER(), чтобы получить то, что вы после:

;with cte AS (SELECT *,COUNT(*) OVER(PARTITION BY DepartmentID) AS Department_CT 
       FROM Employee) 
SELECT * 
FROM cte a 
JOIN Department b 
    ON a.DepartmentID = b.DepartmentID 
WHERE Department_CT = 1 

Это позволяет сохранить полную детализацию, а также возвращение агрегат для фильтрации.

 Смежные вопросы

  • Нет связанных вопросов^_^