【问题标题】:Select only one employee from every department每个部门只选择一名员工
【发布时间】:2019-10-21 18:23:30
【问题描述】:

我希望每个部门(EmpDepartment)都有一名员工,例如在我的表中有:

  • EmpDepartment 1 的 3 名员工
  • EmpDepartment 2 的 2 名员工和
  • EmpDepartment 3 的 1 名员工

我想要来自每个单独部门的任何一名员工的 EmployeeId、EmployeeName 和 EmpDepartment。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    使用这样的窗口函数:

    SELECT *
    FROM (
      SELECT 
         E.*,
         ROW_NUMBER() OVER (PARTITION BY EmpDepartment) AS RN
      FROM Employee
    ) X
    WHERE X.RN = 1
    

    如果您有要用于挑选员工的业务规则,您可以在窗口函数中添加订单子句

    例如

      ROW_NUMBER() OVER (PARTITION BY EmpDepartment order by EmployeeId) AS RN
    

    【讨论】:

    • OVER() 和 PARTITION BY 对我来说是新的,将在未来使用。它适用于我的 order 子句而没有 order 子句它给出错误“函数 'ROW_NUMBER' 必须有一个 OVER 子句订购。”
    • 这是有道理的@AhsanNadeem -- 如果没有 order by,SQL 服务器不支持 -- 这很有趣,因为您可以说 order by empDepartment 这实际上没有任何意义,因为只有每一个。
    【解决方案2】:

    由于按 NEWID() 排序,这将从每个部门随机抽取一名员工...

    SELECT * FROM 
    (
        SELECT EmployeeID, EmployeeName, EmployeeEmail
             , ROW_NUMBER() OVER (PARTITION BY EmpDepartment ORDER BY NEWID()) AS rn
        FROM   dbo.Employee
    ) x 
    WHERE x.rn = 1
    

    您可以根据需要将 order by 子句更改为其他内容。

    【讨论】:

    • 添加为表中的每一行创建随机数的开销究竟有什么好处。
    • 没有它我得到这个错误......“函数'ROW_NUMBER'必须有一个带有ORDER BY的OVER子句。”如果我通过 EmpDepartment 订购,它似乎也有效。如果没有 ORDER BY 子句,它对你有用吗?
    • 是的——在某些平台上你不需要排序——我对 NEWID 的问题是它非常慢——最好是你有索引的列。
    • 好吧,在 SQL Server 2014 上,显然您需要 ORDER BY。
    • 我被 DB2 宠坏了
    【解决方案3】:

    这将返回该部门中具有最小EmployeeID 的每个部门的员工(因为哪个员工将出现在结果中并不重要):

    SELECT e.* FROM Employee e
    WHERE NOT EXISTS (
      SELECT 1 FROM Employee 
      WHERE EmpDepartment = e.EmpDepartment AND EmployeeID < e.EmployeeID
    )
    

    【讨论】:

      【解决方案4】:
      SELECT Top(1) EmployeeID, EmployeeName, EMPDeptartment  FROM Employee WHERE EmpDetpartment = 1
      
      UNION
      
      SELECT Top(1) EmployeeID, EmployeeName, EMPDeptartment  FROM Employee WHERE EmpDetpartment = 2
      
      UNION
      
      SELECT Top(1) EmployeeID, EmployeeName, EMPDeptartment  FROM Employee WHERE EmpDetpartment = 3
      

      【讨论】:

        【解决方案5】:

        您可以使用 rownumber 来查找特定部门的任何员工,将 rn 更改为任何值,例如 1,2,...等

        Select department, employee
        from (
           Select department, employee, 
              row_number() over (partition by department order by employee) rn
        ) 
        where rn =1;
        

        或使用简单的分组方式

        Select department, max(employee)
        from table 
        group by department
        

        【讨论】:

        • 您认为where rn = 2; 有意义的建议令人好奇。 OP 声明部门 3 有一名员工,因此检查 rn 以外的 1 值不会返回该部门的员工。
        • 这很通用
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-02
        • 2012-10-19
        • 1970-01-01
        • 2021-09-09
        • 1970-01-01
        • 2021-01-31
        相关资源
        最近更新 更多