diff --git "a/15\345\220\264\346\230\216\346\235\260/\347\254\224\350\256\260/220908\346\216\222\345\272\217\345\207\275\346\225\260.md" "b/15\345\220\264\346\230\216\346\235\260/\347\254\224\350\256\260/220908\346\216\222\345\272\217\345\207\275\346\225\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..b3d99b4d8231bad7a70c19505b0bb6f82b91a0c6 --- /dev/null +++ "b/15\345\220\264\346\230\216\346\235\260/\347\254\224\350\256\260/220908\346\216\222\345\272\217\345\207\275\346\225\260.md" @@ -0,0 +1,172 @@ +# 四、over开窗函数 + +## (一)开窗函数的定义 + + 它和聚合函数是一样的 ,都是对行的集合组进行聚合计算。它用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,==不需要使用GROUP BY子句对数据进行分组==,能够在同一行中同时返回基础行的列和聚合列。反正我理解这个函数已经使用好子查询或者是其它方式求得聚合列的值给我合并。 + + 但是与聚合函数不同的是,开窗函数在聚合函数后增加了一个OVER关键字。 + +****** + +## (二)开窗函数 + +格式: + +```sql +函数名(列)over(选项) +``` + +### 1.分类 + +- 第一大类:**聚合开窗函数**====》聚合函数(列) OVER (选项),这里的选项可以是PARTITION BY子句,但不可是ORDER BY子句 +- 第二大类:**排序开窗函数**====》排序函数(列) OVER(选项),这里的选项可以是ORDER BY子句,也可以是 OVER(PARTITION BY子句 ORDER BY子句),但不可以是PARTITION BY子句 + +************* + +### 2.开窗的窗口范围 + +`over(order by sroce range between 5 preceding and 5 following)`:窗口范围为当前行数据幅度减5加5后的范围内的。 + +`over(order by sroce rows between 5 preceding and 5 following)`:窗口范围为当前行前后各移动5行。 + +******* + +## (三)聚合开窗函数 + +over[结束] 关键字==表示把聚合函数当成聚合开窗函数而不是聚合函数。SQL 标准允许将所有聚合函数用做聚合开窗函数。== + + 开窗函数的==over关键字后括号中的可以使用partition by 子句来定义行的分区来供进行聚合计算。与group by子句不同,partition by 子句创建的分区是独立于结果集的,创建的分区只是供进行聚合计算的,而且不同的开窗函数所创建的分区也不互相影响。== + +- 在同一个select语句中可以同时使用多个开窗函数,而且这些开窗函数并不会相互干扰。 +- 如果over关键字后的括号中的选项为空,则开窗函数会对结果集中的所有行进行聚合运算。 + +语法: partition[分区] + +```sql +select 聚合函数(列) over (partition by 字段) from b --()里为选项 +``` + +例:**显示每一个人员信息以及所在的班级人数** + +```sql +select *,count(Name) over(partition by ClassId) 人数 from T_Student +``` + +over(partition by ClassId)表示对ClassId进行分区,并且计算当前行所属的组的聚合行数结构,结构默认按照班级ClassId顺序显示,人数列按照count(UserName)显示 + +运行前: + +| stuno | Name | ClassId | +| ----- | ---- | ------- | +| 1001 | 张三 | 3 | +| 1002 | 李四 | 1 | +| 1003 | 王五 | 3 | +| 1004 | 老六 | 2 | +| 1005 | 老七 | 2 | +| 1006 | 老八 | 2 | + +运行后: + +| stuno | Name | ClassId | 人数 | +| ----- | ---- | ------- | ---- | +| 1002 | 李四 | 1 | 1 | +| 1004 | 老六 | 2 | 3 | +| 1005 | 老七 | 2 | 3 | +| 1006 | 老八 | 2 | 3 | +| 1003 | 王五 | 3 | 2 | +| 1001 | 张三 | 3 | 2 | + + + +****** + +## ==(四)排序开窗函数== + +**对于排序开窗函数来讲,它支持的开窗函数分别为:row_number(行号)、rank(排名)、dense_rank(密集排名)和 ntile(分组排名)。** + +**常用的排序函数有3种:** + +- `row_number()` 特点:递增连续的序号,没有并列编号,不跳空编号 +- `rank()` 特点:递增的序号,有并列编号,有跳空编号 +- `dense_rank()` 特点:递增连续的序号,有并列编号,不跳空编号 + +语法: + +```sql +排序函数(列) OVER([partition by] order by 字段[desc][asc])--可以不加分区 +``` + +***** + +### 1.row-number + +这个函数的功能是为查询出来的每一行记录生成一个序号(序号连续的排名)。可以实现排序和分页 + +例:**以score排序生成成绩排名列(序号连续的排名)** + +```sql +select *,row_number()over(order by score ) 成绩排名 from student +``` + +**这个排序开窗函数是按score升序的方式来排序,并得出排序结果的序号** + +实际上,row_number函数生成序号的基本原理是先使用over子句中的排序语句对记录进行排序,然后按着这个顺序生成序号。==over子句中的order by子句与SQL语句中的order by子句没有任何关系== + +注意: + +- 要使用over()子句选择对某一列进行排序才能生成序号,并实现排序。 +- 以班级分区并求第一名成绩的时候,不能用`row_number()`,因为如果同班有两个并列第一,`row_number()`只返回一个结果。 + +*********** + +### 2.rank + +在over子句中排序字段值相同的情况下,排名是相同的,而且排名是不连续的,通常用于返回结果集的分区内每行的排名。 + +例:**以score排序生成成绩排名列(序号不连续的排名),如果成绩相同则名次一致** + +```sql +select *,rank()over( order by score desc) 成绩排名 from student +``` + +******* + +例:**求各班成绩排名** + +```sql +select *,rank()over(partition by classid order by score desc) 班级分区 from student +``` + +这个排序形容函数是按score降序的方式来排序,并得出排序结果的排名号。这个函数求出来的排名结果可以排列,并列排名之后的排名将是并列的排名加上并列数(简单说每个人只有一种排名,然后出现两个并列第一名的情况,这时候排在两个第一名后面的人将是第三名,也就是没有了第二名,但是有两个第一名) + +******* + +### 3.dense-rank + +dense_rank函数的功能与rank函数类似(over子句中排序字段值相同时排名相同),只是在==生成序号时是连续的,而rank函数生成的序号有可能不连续== + +例:**以score排序生成成绩排名列(序号连续的排名),如果成绩相同则名次一致** + +```sql +select *,dense_rank() over( order by score desc) 成绩排名 from student +``` + +******** + +例:**求各班级成绩排名** + +```sql +select *,dense_rank() over(partition by classid order by score desc) 班级分区 from student +``` + +这个排序函数是按score降序的方式来排序,并得出排序结果的排名号。这个函数与rand()函数不同在于,并列排名之后的排名只是并列排名加1(简单说每个人只有一种排名,然后出现两个并列第一名的情况,这时候排在两个第一名后面的人将是第二名,也就是两个第一名,一个第二名) + +******** + +### 4.ntile + +```sql +select *,ntile(4) over( order by score ) 成绩排名 from student +``` + +这个排序函数是按score升序的方式来排序,然后4等分成4个组,并显示所在组的序号。 \ No newline at end of file diff --git "a/15\345\220\264\346\230\216\346\235\260/\347\273\203\344\271\240/220829\345\273\272\350\241\250\347\273\203\344\271\240.md" "b/15\345\220\264\346\230\216\346\235\260/\347\273\203\344\271\240/220829-\345\273\272\350\241\250\347\273\203\344\271\240.md" similarity index 100% rename from "15\345\220\264\346\230\216\346\235\260/\347\273\203\344\271\240/220829\345\273\272\350\241\250\347\273\203\344\271\240.md" rename to "15\345\220\264\346\230\216\346\235\260/\347\273\203\344\271\240/220829-\345\273\272\350\241\250\347\273\203\344\271\240.md" diff --git "a/15\345\220\264\346\230\216\346\235\260/\347\273\203\344\271\240/220907\345\255\220\346\237\245\350\257\242.md" "b/15\345\220\264\346\230\216\346\235\260/\347\273\203\344\271\240/220907-\345\255\220\346\237\245\350\257\242.md" similarity index 100% rename from "15\345\220\264\346\230\216\346\235\260/\347\273\203\344\271\240/220907\345\255\220\346\237\245\350\257\242.md" rename to "15\345\220\264\346\230\216\346\235\260/\347\273\203\344\271\240/220907-\345\255\220\346\237\245\350\257\242.md"