使用参考列列出员工,部门的详细信息

时间:2014-05-09 12:25:13

标签: sql sql-server sql-server-2008

这里我有2个表,EmployeeDepartment,数据如下。

Employee

Empid   Empname Deptid  salary
-----------------------------------------
1       rama    2       20000.00
2       sita    2       30000.00
3       gita    4       45000.00
4       rohit   4       40000.00
5       lata    5       50000.00
6       sami    2       23000.00
7       lala    3       35000.00
8       samta   4       41000.00
9       shika   5       55000.00
10      venu    4       4400.00

Department

Deptid DeptName       DeptReference
---------------------------------------
1      HR                1
2      Engineering       2
3      marketing         1
4      Planning          2
5      Admin             1
6      sales             2

所需的输出是

  • 所有部门的清单,包含n = dept参考部门的n个员工的员工详细信息。
  • 如果n超过该部门的实际员工人数,那么将显示多少现有员工,而其余员工将显示空值

输出:(Deptid, Deptname, empid, empname

提前致谢

纳伦德拉

3 个答案:

答案 0 :(得分:0)

如果查询应忽略每个部门超过n的额外额外员工,请尝试以下操作:

 with DeptEmps (deptId, empSequence) As
   (Select deptId, DeptReference
    From Departments d 
    union all
    Select deptId, empSequence - 1 
    From DeptEmps 
    Where empSequence > 1)

 Select d.DeptId, DeptName, 
    EmpId, EmpName, Salary
 From Departments d
    join DeptEmps de 
       on de.deptId = d.DeptId
   Left Join Employees e
       on e.DeptId = d.DeptId
          And de.empSequence =
            (Select Count(*)
             From Employees
             Where DeptId = e.DeptId
                and EmpId <= e.EmpId)
  Order By d.Deptname

如果查询包含每个部门的额外员工数超过n,那么它会变得更复杂:

with DeptEmps (deptId, empSequence) As
  (Select deptId, 
      Case When d.DeptReference > 
          (Select Count(*) From Employees 
           Where DeptId = d.DeptId) Then d.DeptReference
   Else  (Select Count(*) From Employees 
              Where DeptId = d.DeptId) End empSequence  
   From Depts d 
      union all
   Select deptId, empSequence - 1 
   From DeptEmps 
   Where empSequence > 1)
Select  d.DeptId, DeptName, 
   EmpId, EmpName, Salary
From Depts d
   join DeptEmps de 
      on de.deptId = d.DeptId
   left Join Employees e
     on e.DeptId = de.DeptId
        And (Select Count(*)
             From Employees
             Where DeptId = e.DeptId
                and EmpId <= e.EmpId)
         = de.empSequence          
Order By d.Deptname

答案 1 :(得分:0)

这样做的第一步是每个部门获得n行(其中n是DeptReference),你可以通过交叉加入数字表来实现这一点,我假设你没有并且每次都在飞行中创建一个,但是如果你那么好,你可以使用它:

SELECT  *
FROM    Department d
        CROSS JOIN
        (   SELECT  Number = ROW_NUMBER() OVER(ORDER BY o.object_id) 
            FROM    sys.all_objects o
        ) n
WHERE   n.Number <= d.DeptReference;

或者

SELECT  *
FROM    Department d
        CROSS JOIN Numbers n
WHERE   n.Number <= d.DeptReference;

所以这会给出像

这样的东西
Deptid DeptName       DeptReference Number
1      HR                1          1
2      Engineering       2          1
2      Engineering       2          2

因此工程重复。然后,您需要按部门使用ROW_NUMBER将您的员工置于某种顺序,我不知道您的订单应该是什么,因此只使用EmpID

SELECT  e.DeptID, 
        e.EmpID,
        e.EmpName,
        RowNumber = ROW_NUMBER() OVER(PARTITION BY e.DeptID ORDER BY e.EmpID)
FROM    Employee e;

因此,对于DeptID = 4,这将给出:

Empid   Empname Deptid  RowNUmber
3       gita    4       1
4       rohit   4       2
8       samta   4       3
10      venu    4       4

然后,只需将部门创建的Number列加入为员工创建的RowNumber列。

N.B。如果你想限制所显示的员工,我就无法解决(例如,如果DeptReference是2,而且有3名员工,那么只显示2),如果你想显示所有这些,那么只需取消注释已注释掉的条款

SELECT  d.DeptID,
        d.DeptName,
        e.EmpID,
        e.EmpName
FROM    Department d
        CROSS JOIN
        (   SELECT  Number = ROW_NUMBER() OVER(ORDER BY o.object_id) 
            FROM    sys.all_objects o
        ) n
        LEFT JOIN
        (   SELECT  e.DeptID, 
                    e.EmpID,
                    e.EmpName,
                    RowNumber = ROW_NUMBER() OVER(PARTITION BY e.DeptID ORDER BY e.EmpID)
            FROM    Employee e
        ) e
            ON e.DeptID = d.DeptID
            AND e.RowNumber = n.Number
WHERE   n.Number <= d.DeptReference
--OR        e.EmpID IS NOT NULL
ORDER BY DeptID, EmpID;

由于样本数据中的销售部门没有员工,DeptReference为2,因此这将为销售生成以下内容:

DeptID  DeptName    EmpID   EmpName
6       sales       (null)  (null)
6       sales       (null)  (null)

<强> Example on SQL Fiddle

答案 2 :(得分:0)

您没有说明您将使用哪个标准来选择您希望为每个部门查看哪些员工。我的例子显示了收入最高的员工。无论你选择什么,你都应该能够轻松地改变它。

select
    *
from
(
    select
        e.*
        ,d.DeptReference
        ,ROW_NUMBER() OVER (partition by e.Deptid order by e.salary desc) as Row
    from Employee as e
    inner join Department as d
        on e.Deptid = d.Deptid
)as xx
where xx.Row <= xx.DeptReference;