根据子表的计数选择行

时间:2016-12-28 00:15:41

标签: sql-server tsql

我有三个实体:部门,员工和报告。一个部门有很多员工,每个员工都有很多报告。我想选择每个部门中报告最多的一名员工。我不知道如何开始这个查询。 This question似乎非常相似,但我无法弄清楚如何根据我的需要操纵这些答案。

我可以完全访问整个系统,因此我可以进行必要的更改。如果出现平局,可以随意选择其中一个结果。

系:

 ID | Name
----|------
  1 | DeptA
  2 | DeptB
  3 | DeptC
  4 | DeptD

员工:

 ID | Name | DeptID
----|------|--------
  1 | Joe  | 1
  2 | John | 1
  3 | Emma | 2
  4 | Jack | 3
  5 | Sven | 3
  6 | Axel | 4
  7 | Brad | 4
  8 | Jane | 4

报告:

 ID | EmployeeID
----|------------
  1 | 1
  2 | 2
  3 | 3
  4 | 5
  5 | 6
  6 | 6
  7 | 8

期望的结果(假设我只查询名称):

Joe OR John (either is acceptable)
Emma
Sven
Axel

3 个答案:

答案 0 :(得分:5)

如何开始此查询?那么,获取有关每个员工,部门和报告数量的信息:

row_number()

现在你只想要每个部门的最大数量。我会建议rank()select er.* from (select e.name, e.deptid, count(*) as numreports, row_number() over (partition by e.deptid order by count(*) desc) as seqnum from employee e join reports r on e.id = r.employeeid group by e.name, e.deptid ) er where seqnum = 1; ,具体取决于您希望如何处理关系:

{{1}}

如果您想要部门名称而不是数字,您也可以将其加入。

答案 1 :(得分:2)

来自您的问题架构

SELECT *  into  #Department FROM(
select 1 ID,'DEPTA' NAME
UNION ALL
select 2,'DEPTB'
UNION ALL
select 3,'DEPTC'
UNION ALL
select 4,'DEPTD')TAB

SELECT * INTO #Employee FROM (

SELECT  1 ID  ,'Joe' Name ,  1 DeptID
UNION ALL
SELECT 2 , 'John'  , 1
UNION ALL
SELECT 3 , 'Emma'  ,2
UNION ALL
SELECT 4  ,'Jack' , 3
UNION ALL
SELECT 5  ,'Sven' , 3
UNION ALL
SELECT 6 , 'Axel' , 4
UNION ALL
SELECT 7  ,'Brad' , 4
UNION ALL
SELECT 8  ,'Jane' , 4)AS A

SELECT * INTO  #Report FROM(
SELECT 1 ID  ,1 EmployeeID
UNION ALL
SELECT 2,  2
UNION ALL
SELECT 3  ,3
UNION ALL
SELECT 4,  5
UNION ALL
SELECT 5,  6
UNION ALL
SELECT 6,  6
UNION ALL
SELECT 7,  8
UNION ALL
SELECT 8,  8
UNION ALL
SELECT 9,  8
)AS A

您需要应用DENSE_RANK()根据报告(计数)

给出排名
;WITH CTE AS(
select DEP.ID DEP_ID, DEP.NAME DEP,EMP.ID EMP_ID, EMP.Name EMP
,DENSE_RANK() OVER(PARTITION BY DEP.ID ORDER BY  COUNT(REP.ID)  DESC) REP_RANK
,COUNT(REP.ID) NO_OF_REP FROM #Department DEP
inner join #Employee emp on emp.deptid=dep.id
inner join #report rep on rep.EmployeeID=emp.id
GROUP BY DEP.ID, DEP.NAME ,EMP.ID, EMP.Name 
)
SELECT DEP, EMP, NO_OF_REP FROM CTE WHERE REP_RANK=1

DEPTA Joe& John将被选中,因为两者都有1个报告计数,这是DEPTA中的最大计数。

结果将是

+-------+------+-----------+
|  DEP  | EMP  | NO_OF_REP |
+-------+------+-----------+
| DEPTA | Joe  |         1 |
| DEPTA | John |         1 |
| DEPTB | Emma |         1 |
| DEPTC | Sven |         1 |
| DEPTD | Jane |         3 |
+-------+------+-----------+

答案 2 :(得分:0)

请尝试以下代码: -

SELECT D.NAME
FROM (
    SELECT C.NAME, RANK() OVER (
            PARTITION BY C.DEPTID ORDER BY C.COUNTS DESC
            ) RNK
    FROM (
        SELECT EMPID, NAME, COUNT(EMPID) AS COUNTS, DEPTID
        FROM DBO.REPORT AS A
        JOIN DBO.EMPLO AS B ON A.EMPID = B.ID
        GROUP BY EMPID, NAME, DEPTID
        ) AS C
    ) AS D
WHERE D.RNK = 1