列出员工、部门的详细信息并附有参考栏

问题描述 投票:0回答:3

这里我有2个表,

Employee
Department
,数据如下。

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 名员工的员工详细信息,其中 n = 部门的部门参考。
  • 如果 n 超过该部门的实际员工数量,则显示尽可能多的现有员工,而其余员工将显示空值

输出:(

Deptid, Deptname, empid, empname
)

提前致谢

纳兰德拉

sql sql-server sql-server-2008
3个回答
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;

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
列即可。

注意我不知道你是否想限制显示的员工(即如果 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)

SQL Fiddle 示例


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
© www.soinside.com 2019 - 2024. All rights reserved.