具有等级的postgres窗口函数

Posted

技术标签:

【中文标题】具有等级的postgres窗口函数【英文标题】:postgres window function with rank 【发布时间】:2016-12-22 11:41:54 【问题描述】:

我有一些记录显示用户的薪水和部门。 我想知道排名及其差异。

SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary DESC) FROM empsalary;
  depname  | empno | salary | rank 
-----------+-------+--------+------
 develop   |     8 |   6000 |    1
 develop   |    10 |   5200 |    2
 develop   |    11 |   5200 |    2
 develop   |     9 |   4500 |    4
 develop   |     7 |   4200 |    5
 personnel |     2 |   3900 |    1
 personnel |     5 |   3500 |    2
 sales     |     1 |   5000 |    1
 sales     |     4 |   4800 |    2
 sales     |     3 |   4800 |    2

我想知道每个级别的薪水差异

  depname  | empno | salary | rank | diff
-----------+-------+--------+------+------
 develop   |     8 |   6000 |    1 | 800
 develop   |    10 |   5200 |    2 | 700
 develop   |    11 |   5200 |    2 | 700
 develop   |     9 |   4500 |    4 | 300
 develop   |     7 |   4200 |    5 | 
 personnel |     2 |   3900 |    1 | 400
 personnel |     5 |   3500 |    2 | 
 sales     |     1 |   5000 |    1 | 200
 sales     |     4 |   4800 |    2 | 
 sales     |     3 |   4800 |    2 | 

教我上面返回的查询。

【问题讨论】:

【参考方案1】:

只需使用lag():

SELECT depname, empno, salary,
       rank() OVER (PARTITION BY depname ORDER BY salary DESC) as rnk,
       (salary - lag(salary) over (partition by depname order by salary desc)) as diff
FROM empsalary;

编辑:

我注意到您的数据有重复 - 因此是 rank()。这有点麻烦,因为 Postgres 不支持完整的range 关键字。这是一种不使用JOIN的方法:

SELECT depname, empno, salary, rnk,
       (salary - MIN(prev_salary) OVER (PARTITION BY depname, rnk)) as diff
FROM (SELECT depname, empno, salary,
             rank() OVER (PARTITION BY depname ORDER BY salary DESC) as rnk,
             lag(salary) over (partition by depname order by salary desc) as prev_salary
      FROM empsalary
     ) e;

【讨论】:

【参考方案2】:
SELECT depname,empno, salary, rank() 
OVER (PARTITION BY depname ORDER BY salary DESC) AS rnk, salary-lag(salary) 
OVER (partition BY depname ORDER BY  salary ) AS diff 
FROM empsalary ORDER BY depname, salary DESC;

【讨论】:

您好尝试回答 mo12mo34 问题 ;-) 请对此添加一些解释,以便人们了解它的工作原理 salary-lag(salary) 按部门名称给出工资差异 虽然这可以回答问题,但仅包含代码而没有说明代码如何工作的答案可能会被标记为低质量。考虑添加一些文本来解释可能有助于 OP 和未来访问者访问这篇文章的代码。此外,这样,您更有可能在该问题上获得积分。

以上是关于具有等级的postgres窗口函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Postgres 的窗口函数中获取 mode()?

如何使用窗口函数枚举 Postgres 表中的分区组?

如何计算具有窗口函数的过滤器的总数?

如何在带有 Postgres 的动态框架中使用窗口函数中的列值?

Postgres 窗口函数语法

自定义窗口函数忽略 Postgres 中的空值