分析函数: ...... OVER ( PARTITION BY ...... ORDER BY ...... ) 使用方法讲解

在开发中遇到了一个需求: 

       有一张进度表ProgressMonthly 字段有 id, projectid, year,  month, complete

        分析函数: ...... OVER ( PARTITION BY ...... ORDER BY ...... ) 使用方法讲解_第1张图片

目标是: 统计所有项目的最新月份的complete 数量

解决思路: 使用分析函数: ......OVER ( PARTITION BY  ......  ORDER BY ...... ) 筛选出每个项目的最新月份的数据然后sum()

常用的分析函数有:

  1. row_number()  over(partition by ... order by ...)
  2. rank()  over(partition by ... order by ...)
  3. dense_rank()  over(partition by ... order by ...)
  4. count()  over(partition by ... order by ...)
  5. max()  over(partition by ... order by ...)
  6. min()  over(partition by ... order by ...)
  7. sum()  over(partition by ... order by ...)
  8. avg()  over(partition by ... order by ...)
  9. first_value()  over(partition by ... order by ...)
  10. last_value()  over(partition by ... order by ...)
  11. lag()  over(partition by ... order by ...)
  12. lead()  over(partition by ... order by ...)

首先分析一下 OVER ( PARTITION BY  a  ORDER BY b ) 是什么意思

就是先把一组数据按照a这个字段进行分割成多个组,然后组内按照b这个字段进行排序

举个例子:

SELECT  * , 
        ROW_NUMBER() OVER(PARTITION BY Y.Year ORDER BY Y.Month DESC ) RNO 
from ProgressMonthly Y

输出如下:

分析函数: ...... OVER ( PARTITION BY ...... ORDER BY ...... ) 使用方法讲解_第2张图片

如上图数据会根据year分成2组,每一组会根据month进行排序.

其次,我们在分析一下哪个分析函数适合这个需求

根据我们的需求我们将会在ROW_NUMBER()... , RANK()... 和 DENSE_RANK()... 这三个分析函数选择,它们的区别在哪里呢?

1.ROW_NUMBER()...在遇到month参数相同时也会进行排序

如下图:

分析函数: ...... OVER ( PARTITION BY ...... ORDER BY ...... ) 使用方法讲解_第3张图片

2.RANK()... 和 DENSE_RANK()...在遇到month参数相同时 ,相同参数的排序是一样的

如下图:

分析函数: ...... OVER ( PARTITION BY ...... ORDER BY ...... ) 使用方法讲解_第4张图片

3. 那RANK()... 和 DENSE_RANK()...的区别在哪呢?

RANK()... 输出如下图(注意红框):

分析函数: ...... OVER ( PARTITION BY ...... ORDER BY ...... ) 使用方法讲解_第5张图片

DENSE_RANK()...输出如下图(注意红框):

分析函数: ...... OVER ( PARTITION BY ...... ORDER BY ...... ) 使用方法讲解_第6张图片

由图可见:

RANK()...

相同参数保持一致排序后,后面元素还是保持原本排序

DENSE_RANK()...

相同参数保持一致排序后,后面元素还是跟随排序

最后我采用了DENSE_RANK()...OVER ( PARTITION BY  ......  ORDER BY ...... ) 分析函数进行实现需求

代码如下:

SELECT  * 
from (
	SELECT *,
	DENSE_RANK() OVER(PARTITION BY Y.Year ORDER BY Y.Month DESC ) RNO, 
	DENSE_RANK() OVER( ORDER BY Y.Year DESC ) RNO2 from ProgressMonthly Y 
) X
where x.RNO = 1 AND x.RNO2 = 1
ORDER BY YEAR DESC 

输出结果:

分析函数: ...... OVER ( PARTITION BY ...... ORDER BY ...... ) 使用方法讲解_第7张图片

最后进行Group up ...   SUM()出所有项目的统计值:

代码如下:

SELECT  SUM(X.Complete) AS sumComplete
from (
	SELECT Y.Year,Y.Complete,
	DENSE_RANK() OVER(PARTITION BY Y.Year ORDER BY Y.Month DESC ) RNO, 
	DENSE_RANK() OVER( ORDER BY Y.[Year] DESC ) RNO2 from ProgressMonthly Y 
) X
where X.RNO = 1 AND X.RNO2 = 1
GROUP BY X.Year
ORDER BY YEAR DESC 

输出如下:

大功告成!!!

你可能感兴趣的:(开发中的问题归纳)