【问题标题】:Quite a tricky SQL query相当棘手的 SQL 查询
【发布时间】:2013-05-31 07:31:50
【问题描述】:

我有一个表EMPLOYEE 有 3 个字段:

EMPLOYEE(ROLE SMALLINT, RATING INTEGER, NAME VARCHAR)

我只需要从这个表中获取 3 行。它是每种类型的一排,在其类型中具有最高评级。字段的角色 - 是从三个值列表中定义特定角色的判别式:DEVELOPER(1)、TESTER(2)、MANAGER (3)。所以 ROLE 字段的值可以是 1 或 2 或 3。

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    这是一个基本的聚合查询(我假设您是 SQL 新手):

    select role, max(rating)
    from employee
    group by role
    

    回应评论(我可以看到这个问题是多么模棱两可)。在 Postgres 中执行此操作的正确方法是使用窗口函数:

    select role, rating, name
    from (select e.*,
                 row_number() over (partition by role order by rating desc) as seqnum
          from employee e
         ) e
    where seqnum = 1
    

    这个版本只返回一行,即使有重复。如果您希望所有行都具有相同的最大值,请使用rank() 而不是row_number()

    【讨论】:

    • NAME 字段在哪里?语句 GROUP BY role 在 SELECT 中不能与 NAME 一起正常工作
    • 我认为 row_number() 需要按角色分区
    • @dotjoe 。 . .谢谢你。我修好了。
    【解决方案2】:

    Postgres 特定的短查询:

    SELECT DISTINCT ON (role) role, name, rating
    FROM employee
    ORDER BY role, rating DESC
    

    如果 2 名员工具有相同的角色和等级 - 将随机选择其中一名。

    【讨论】:

      【解决方案3】:

      如果我正确理解您的问题,您希望为每个角色提供评分最高的名称:

      select role, rating, name
      from employee as e1
      where rating = (
        select max(rating) from employee
        where role = e1.role
      )
      

      但是,如果您有两个具有相同角色和评级的员工,这将无法正常工作。在这种情况下,您需要在子查询中选择名称。

      【讨论】:

        猜你喜欢
        • 2016-01-12
        • 1970-01-01
        • 1970-01-01
        • 2013-08-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多