添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
大鼻子的海龟  ·  jq ...·  7 月前    · 
果断的凉茶  ·  js去掉url中的域名 - ...·  2 年前    · 

摘自作者新书《锋利的SQL》(第2版),网购京东: http://item.jd.com/11692900.html

SQL Server2012 开始,提供了四个排名分布函数,包括 PERCENT_RANK CUME_DIST PERCENTILE_CONT PERCENTILE_DISC 。其中 PERCENT_RANK 用于计算某行的相对排名, CUME_DIST 用于计算行的累积分布(即相对位置), PERCENTILE_CONT PERCENTILE_DISC 用于根据指定的比例返回组中相应的数值,如中位值等。换句话说, PERCENT_RANK CUME_DIST 是根据数值计算比例, PERCENTILE_CONT PERCENTILE_DISC 是根据指定的比例计算数值,类似于对 PERCENT_RANK CUME_DIST 的逆运算。

9.4.1 PERCENT_RANK 函数

PERCENT_RANK 用于计算某行的相对排名,返回一个 0 1 之间的一个小数值。该函数的 OVER 子句允许有分区和排序子句,并且排序子句是必选项。

下面通过一个示例来说明这种相对排名的计算方法,这里我们仍旧使用 9.1 节创建的 Students 表,下面的语句用于计算学生成绩在自己班级的绝对排名和相对排名,查询结果如表 9-15 所示。

SELECT ClassID, StudentName, Achievement,

RANK() OVER(PARTITION BY ClassID ORDER BY Achievement DESC) AS A_Rank,

PERCENT_RANK() OVER(PARTITION BY ClassID ORDER BY Achievement DESC) ASP_Rank

FROM dbo.Students;

9-15 学生成绩在自己班级的绝对排名和相对排名

ClassID

StudentName

Achievement

A_Rank

P_Rank

1

Grace

99

1

0

1

Andrew

99

1

0

1

Margaret

89

3

0.666667

1

Janet

75

4

1

2

Robert

91

1

0

2

Steven

86

2

0.5

2

Michael

72

3

1

3

Ann

94

1

0

3

Ken

92

2

0.333333

3

Ina

80

3

0.666667

3

Laura

75

4

1

对于使用 RANK 函数获得绝对排名,我们在前面已经介绍过。现在看表中的 P_Rank 列的计算方法,公式如下:

(当前行的 RANK 排名 -1 / (分区内总行数 -1

从表中可以看出, Grace Andrew RANK 排名为第 1 ,并且当前分区内共有 4 行,所以第一行和第二行的 P_Rank 列值均计算为: (1-1)/(4-1)=0 。第三行 Margaret P_Rank 列值计算方法为: (3-1)/(4-1)=0.666667 ,表示班级内有 66.667% 的人高于自己的成绩。

9.4.2 CUME_DIST 函数

CUME_DIST 用于计算某个值在一组值内的累积分布,也可以说是该值在一组值中的相对位置。函数返回一个 0 1 之间的一个小数值。该函数的 OVER 子句允许有分区和排序子句,并且排序子句是必选项。

下面通过一个示例来说明这种相对位置的计算方法,仍旧使用 9.1 节创建的 Students 表。下面的语句中, C_Num 列计算的是大于或等于自己学生成绩的人数, C_Dist 列计算的是大于或等于自己学生成绩的人数占全班人数的比例,查询结果如表 9-16 所示。

SELECT ClassID, StudentName, Achievement,

COUNT(*) OVER(PARTITION BY ClassID ORDER BY Achievement DESC) AS C_Num,

CUME_DIST() OVER(PARTITION BY ClassID ORDER BY Achievement DESC) ASC_Dist

FROM dbo.Students;

9-16 计算的是大于或等于自己学生成绩的人数及占全班人数的比例

ClassID

StudentName

Achievement

C_Num

C_Dist

1

Grace

99.00

2

0.5

1

Andrew

99.00

2

0.5

1

Margaret

89.00

3

0.75

1

Janet

75.00

4

1

2

Robert

91.00

1

0.333333333333333

2

Steven

86.00

2

0.666666666666667

2

Michael

72.00

3

1

3

Ann

94.00

1

0.25

3

Ken

92.00

2

0.5

3

Ina

80.00

3

0.75

3

Laura

75.00

4

1

表中 C_Dist 列的计算公司为:

C_Num/ 班级总人数

C_Num 是大于或等于自己学生成绩的人数。表中第 1 4 行是班级 1 的数据,第一行和第二行 C_Dist 列值的计算方法是: 2/4=0.5 ,表示班级中有 50% 的大于或等于自己的成绩。

9.4.3 PERCENTILE_CONT PERCENTILE_DISC 函数

PERCENTILE_CONT PERCENTILE_DISC 用于根据指定的比例返回一组数据中相应位置的值,所指定比例应当是一个 0 1 之间的小数。例如,比例为 0.5 (即中位值),这组数字是 1 3 9 12 18 ,则这个数值应当是 9

PERCENTILE_CONT PERCENTILE_DISC 函数的语法格式如下,其中的 WITHIN GROUP 子句用于指定要排序的数值列表, OVER 子句可以指定一个分区列。

PERCENTILE 函数 (numeric_literal )

WITHINGROUP ( ORDER BY order_by_expression [ ASC | DESC ] )

OVER ( [<partition_by_clause> ] )

下面通过示例来说明这两个函数的使用方法,参考下面的语句。查询结果如表 9-17 所示。

SELECT ClassID, StudentName, Achievement,

PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BYAchievement DESC)

OVER(PARTITION BYClassID) AS P_Cont,

PERCENTILE_DISC(0.6) WITHIN GROUP (ORDER BYAchievement DESC)

OVER(PARTITION BYClassID) AS P_Disc,

CUME_DIST() OVER(PARTITION BY ClassID

ORDER BY Achievement DESC) AS C_Dist

FROM dbo.Students;

9-17 根据指定比例返回相应数值

ClassID

StudentName

Achievement

P_Cont

P_Disc

C_Dist

1

Grace

99

94

89

0.5

1

Andrew

99

94

89

0.5

1

Margaret

89

94

89

0.75

1

Janet

75

94

89

1

2

Robert

91

86

86

0.333333

2

Steven

86

86

86

0.666667

2

Michael

72

86

86

1

3

Ann

94

86

80

0.25

3

Ken

92

86

80

0.5

3

Ina

80

86

80

0.75

3

Laura

75

86

80

1

表中 P_Cont 列计算的是班级中 50% 位置的值,班级 1 共有 4 行,因此 94 Achievement 列中第二行和第三行的平均值: (99+89)/2 。也就是说,对于偶数行, PERCENTILE_CONT 函数计算的是中间两个数值间的平均值。

PERCENTILE_DISC函数不会这样做,它始终返回的是已有值。注意表中的C_Dist列,该列计算的是值得累积分布。当为PERCENTILE_DISC指定一个比例值时,它会查找大于或等于该比例的累积分布值所对应的值。例如,在该示例中我们为函数指定的比例是0.6,在班级1中第一个大于或等于该值的累积分布是0.75,因此该函数返回了89。 Overall_ dis tribution = spark. sql (""" select count(*) as total_, round(count(case when Completion_rate >= 0 and Completion_rate < 0.25 then 1 end )/count(*),2) as a, round(count(case when Completion_rate >= 0.25 and. 今天的所有数据:select * from 表名 where DateDiff(dd,datetime类型字段,getdate())=0 昨天的所有数据:select * from 表名 where DateDiff(dd,datetime类型字段,getdate())=1 7天内的所有数据:select * from 表名 where DateDiff(dd,datetime类... curdate( ) AS date UNION ALL SELECT date_sub( curdate( ), INTERVAL 1 DAY ) AS date UNION ALL SELECT date_sub( curdate( ), INTERVAL 2 DAY ) AS date UNION ALL SELECT date_su 一、场景简介 以下内容是对该问题和经验分享的场景进行简介,可以通过此部分查看此文章内容是否为你可以参考的内容。 使用 SQL 查询实现分区间/分段统计。该 sql 使用常存在于报表的制作,统计数据的 计算 ,大屏数据展示等场景。通常我们会面对一类需求,将一组或一批或一张表的数据,根据某一字段按照分段、分区间(有时是自定义区间)的形式,进行汇总统计, 计算 相关数值、占比等。譬如以下场景: 统计某班级(或其他类似团体)某次测试分数 分布 计算 某站点访问量随时间变化的曲线 某地区/某行