MYSQL 基于多列的Rank

标签 mysql rank window-functions row-number

我正在尝试在 mysql 中创建一个查询,以根据多列分配行号。以下是我需要所需结果的格式

    CN   PN  GroupName  WeekTimeReported    rank    desired_rank    

    X   ProjX   A       12/30/2013           1         1    
    X   ProjX   B       12/30/2013           2         1    
    X   ProjX   C       1/6/2014             3         2    
    X   ProjX   D       1/6/2014             4         2    
    Y   ProjY   A       1/13/2014            5         1    
    Y   ProjY   B       1/13/2014            6         1    
    Y   ProjY   C       1/20/2014            7         2    
    Y   ProjY   D       1/20/2014            8         2    
    Z   ProjZ   A       1/27/2014            9         1    
    Z   ProjZ   B       1/27/2014           10         1    
    Z   ProjZ   C       2/3/2014            11         2    
    Z   ProjZ   D       2/3/2014            12         2    

我希望我的结果采用 desired_rank 列格式。因此,对于相同的 CN 和 PN,我想根据 WeekTimeReported 进行排名(我想查看项目进行的周数)。提前感谢您的帮助。

这是 SQLFiddle并查询:

SELECT 
 @cn:=ClientName ClientName
,ProjectName
,GroupName
,CAST(WeekTimeReported AS DATE) WeekTimeReported
,@rc:= CASE WHEN @cn=ClientName THEN @rc+1 ELSE 1 END AS rc
,desired_rank
,Hours
FROM sampledata , (select @rc:=0, @cn='') as rc

最佳答案

您需要考虑各个列的所有数据变化。


这是查询在 MySQL 8.0 中的样子

select
*
, dense_rank() over(partition by `ClientName` order by `WeekTimeReported`,`ProjectName`) rnk
from sampledata
ClientName | ProjectName | GroupName | WeekTimeReported | rank | desired_rank | Hours | rnk
:--------- | :---------- | :-------- | :--------------- | ---: | -----------: | ----: | --:
X          | ProjX       | A         | 2013-12-30       |    1 |            1 |     2 |   1
X          | ProjX       | B         | 2013-12-30       |    2 |            1 |    10 |   1
X          | ProjX       | C         | 2014-01-06       |    3 |            2 |     4 |   2
X          | ProjX       | D         | 2014-01-06       |    4 |            2 |     2 |   2
Y          | ProjY       | A         | 2014-01-13       |    5 |            1 |     3 |   1
Y          | ProjY       | B         | 2014-01-13       |    6 |            1 |     1 |   1
Y          | ProjY       | C         | 2014-01-20       |    7 |            2 |     6 |   2
Y          | ProjY       | D         | 2014-01-20       |    8 |            2 |     1 |   2
Z          | ProjZ       | A         | 2014-01-27       |    9 |            1 |     4 |   1
Z          | ProjZ       | B         | 2014-01-27       |   10 |            1 |     1 |   1
Z          | ProjZ       | C         | 2014-02-03       |   11 |            2 |    17 |   2
Z          | ProjZ       | D         | 2014-02-03       |   12 |            2 |    16 |   2

db<> fiddle here


这是对旧版 MySQL 的部分回答,希望可以帮助您实现目标:

查询 1:

select
rc - rcwk
, d.*
from (
SELECT 
  @rcwk:= CASE WHEN @cnwk=concat(ClientName,WeekTimeReported) THEN @rcwk+1 ELSE 1 END AS rcwk
, @rc:= CASE WHEN @cn=ClientName THEN @rc+1 ELSE 1 END AS rc
, desired_rank
, ClientName
, ProjectName
, GroupName
, CAST(WeekTimeReported AS DATE) WeekTimeReported
, Hours
, @cn:=ClientName
, @cnwk:=concat(ClientName,WeekTimeReported) abc
FROM sampledata 
cross join (select @rc:=0,@rcwk:=0, @cn='',@cnwk='' ) as rc
order by ClientName, ProjectName, WeekTimeReported
  ) d

Results :

| rc - rcwk | rcwk | rc | desired_rank | ClientName | ProjectName | GroupName | WeekTimeReported | Hours | @cn:=ClientName |         abc |
|-----------|------|----|--------------|------------|-------------|-----------|------------------|-------|-----------------|-------------|
|         0 |    1 |  1 |            1 |          X |       ProjX |         A |       2013-12-30 |     2 |               X | X2013-12-30 |
|         0 |    2 |  2 |            1 |          X |       ProjX |         B |       2013-12-30 |    10 |               X | X2013-12-30 |
|         2 |    1 |  3 |            2 |          X |       ProjX |         C |       2014-01-06 |     4 |               X | X2014-01-06 |
|         2 |    2 |  4 |            2 |          X |       ProjX |         D |       2014-01-06 |     2 |               X | X2014-01-06 |
|         0 |    1 |  1 |            1 |          Y |       ProjY |         A |       2014-01-13 |     3 |               Y | Y2014-01-13 |
|         0 |    2 |  2 |            1 |          Y |       ProjY |         B |       2014-01-13 |     1 |               Y | Y2014-01-13 |
|         2 |    1 |  3 |            2 |          Y |       ProjY |         D |       2014-01-20 |     1 |               Y | Y2014-01-20 |
|         2 |    2 |  4 |            2 |          Y |       ProjY |         C |       2014-01-20 |     6 |               Y | Y2014-01-20 |
|         0 |    1 |  1 |            1 |          Z |       ProjZ |         A |       2014-01-27 |     4 |               Z | Z2014-01-27 |
|         0 |    2 |  2 |            1 |          Z |       ProjZ |         B |       2014-01-27 |     1 |               Z | Z2014-01-27 |
|         2 |    1 |  3 |            2 |          Z |       ProjZ |         C |       2014-02-03 |    17 |               Z | Z2014-02-03 |
|         2 |    2 |  4 |            2 |          Z |       ProjZ |         D |       2014-02-03 |    16 |               Z | Z2014-02-03 |

关于MYSQL 基于多列的Rank,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34319552/

相关文章:

php - 允许 php 软件在不超过 3 个计算中运行

python - SQLAlchemy 在同一事务中删除和插入

排除子查询结果的 MySQL 'WHERE' 子句

选择排名查询后的 MySql Where 条件

sql - 在 PostgreSQL 中滚动 12 个月的总和

sql - 如何使用 Lag Lead 或窗口函数根据列值合并行开始日期结束日期?

python:如何获取mysql数据库更改的通知?

SQL:获取结果查询中的位置

mysql - 如何按多个等级对表进行排序

python - Spark SQL Row_number() PartitionBy Sort Desc