2016-12-28 19 views
0

私には、部門、従業員、およびレポートの3つのエンティティがあります。部門には多くの従業員がおり、それぞれに多くの報告書があります。最も多くの報告を受けている各部門の従業員を1つ選択したいと考えています。私はこのクエリを開始する方法も知らない。 This questionは非常によく似ているようですが、私が望むものに対してはそれらの答えを操作する方法を理解できません。子テーブルのカウントに基づいて行を選択します。

私はシステム全体に完全にアクセスできるため、必要な変更を加えることができます。同調の場合、結果の1つを任意に選択することは安全です。

部門:

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 

答えて

5

このクエリを開始するには?各従業員、部署、レポート数についての情報を入手してください。

select e.name, e.deptid, count(*) as numreports 
from employee e join 
    reports r 
    on e.id = r.employeeid 
group by e.name, e.deptid; 

これで、各部門で最大のカウントが必要になります。私はあなたが関係を処理する方法に応じて、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つを選ぶ。 – Blorgbeard

+0

@Blorgbeardが提案したように、左の結合を使用しました。どうもありがとうございます! – vaindil

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ジョー&ジョンの両方になりますどちらもDEPTAの最大カウントである1つのレポート・カウントを持つため、選択されます。

そして結果は

+-------+------+-----------+ 
| DEP | EMP | NO_OF_REP | 
+-------+------+-----------+ 
| DEPTA | Joe |   1 | 
| DEPTA | John |   1 | 
| DEPTB | Emma |   1 | 
| DEPTC | Sven |   1 | 
| DEPTD | Jane |   3 | 
+-------+------+-----------+ 
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 
関連する問題