数据库
首页 > 数据库> > SqlServer开窗函数

SqlServer开窗函数

作者:互联网

 https://www.bilibili.com/video/BV1k44y1Y73j?p=1&vd_source=4c907fba67f1d94da623c068af8ed9d8

一、什么是窗口函数(开窗函数)

简单来说,对数据结果集不破坏原来的,进行聚合、排名、统计分析操作。支持数据库,Mysql8.0,Mssqlerver 2012,oracle 10g

 

基本语法:OVER ( [ partition_by_clause ] order_by_clause ),详细语法如下:

OVER (

       [ <PARTITION BY clause> ]

       [ <ORDER BY clause> ]

       [ <ROW or RANGE clause> ]

      ) 

 

<PARTITION BY clause> ::=

PARTITION BY value_expression , ... [ n ]

 

<ORDER BY clause> ::=

ORDER BY order_by_expression

    [ COLLATE collation_name ]

    [ ASC | DESC ]

    [ ,...n ]

 

<ROW or RANGE clause> ::=

{ ROWS | RANGE } <window frame extent>

 

<window frame extent> ::=

{   <window frame preceding>

  | <window frame between>

}

 

<window frame between> ::=

  BETWEEN <window frame bound> AND <window frame bound>

 

<window frame bound> ::=

{   <window frame preceding>

  | <window frame following>

}

 

<window frame preceding> ::=

{

    UNBOUNDED PRECEDING

  | <unsigned_value_specification> PRECEDING

  | CURRENT ROW

}

 

<window frame following> ::=

{

    UNBOUNDED FOLLOWING

  | <unsigned_value_specification> FOLLOWING

  | CURRENT ROW

}

 

<unsigned value specification> ::=

{  <unsigned integer literal> }

 

二、docker 安装sql server 2019

 

https://www.jianshu.com/p/70baab8006c3

 

docker pull mcr.microsoft.com/mssql/server:2019-latest

docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=SA@12345"  -p 1435:1433 --name sql-server2019 -h sql-server2019 -d mcr.microsoft.com/mssql/server:2019-latest

 

说明:

-e "ACCEPT_EULA=Y" 将 ACCEPT_EULA 变量设置为任意值,以确认接受 最终用户许可协议。 SQL Server 映像的必需设置。

-e "SA_PASSWORD=<YourStrong@Passw0rd>"  指定至少包含 8 个字符且符合 SQL Server 密码要求的强密码。 SQL Server 映像的必需设置。 默认情况下,密码的长度必须至少为 8 个字符,并且必须包含以下四种字符中的三种:大写字母、小写字母、十进制数字和符号

-p 1435:1433    将主机环境中的 TCP 端口(第一个值)映射到容器中的 TCP 端口(第二个值) 

注意端口:127.0.0.1,1435

 

 

 

 

 

中文乱码问题:https://blog.csdn.net/xingkongtianyuzhao/article/details/103944280

 

改一下表结构:中文字段加上,COLLATE Chinese_PRC_CI_AS解决

 

 

 

三、实操

参考文档:

https://www.cnblogs.com/longling2344/p/5704384.html

https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2012/ms189461(v=sql.110)?redirectedfrom=MSDN

 

https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2012/hh231256(v=sql.110)

 

基本实践:

Select count(ipt_no) from ip_rec  

Select count(ipt_no),t.* over() from ip_rec

 

 

SELECT t.*,COUNT (t.ipt_no) OVER (PARTITION BY t.adm_dept_codg) 按科室计算人次 FROM

ip_rec t order by t.adm_dept_codg,t.ipt_no;

 

SELECT t.*,COUNT (ipt_no) OVER (PARTITION BY t.adm_dept_codg,t.doctor_codg) 按科室和医生计算人数 FROM ip_rec t

 order by t.adm_dept_codg,t.doctor_codg,t.ipt_no;

 

PARTITION BY作用相当于group by  

select  t.adm_dept_name,count(t.ipt_no) from ip_rec t group by t.adm_dept_name

 

 

实操案例:

需求1:需要统计24小时之内出入院的患者信息

注意:lag,lead要msssql2012才能支持

 

SELECT

pkid,

ipt_no,

pat_name,

pat_sex,

adm_date,

dscg_date,

  lag(t.dscg_date,1) OVER (PARTITION BY t.ipt_no order by t.adm_date) 上一次出院日期,

lead(t.dscg_date,1) OVER (PARTITION BY t.ipt_no order by t.adm_date) 下一次入院日期,

adm_dept_codg,

adm_dept_name,

dscg_dept_codg,

dscg_dept_name,

doctor_codg,

doctor_name

FROM

ip_rec t

ORDER BY

t.ipt_no,

t.adm_date

 

 

 

 

需求2:统计患者住院次数

SELECT

rank() OVER (PARTITION BY t.ipt_no order by t.adm_date) 住院次数,  

t.*

FROM

ip_rec t

ORDER BY

t.ipt_no,

t.adm_date

 

 

 

需求3:某个患者多次住院费用累加

 

ROWS BETWEEN 2 PRECEDING AND CURRENT ROW 意味着该函数对其操作的行的窗口在大小上是 3 行、以当前行之前(包括当前行)的 2 行开头。

 

SELECT

pkid,

ipt_no,

pat_name,

pat_sex,

adm_date,

dscg_date,

t.fee,

SUM (fee) OVER (

PARTITION  BY t.ipt_no

ORDER BY t.adm_date

    ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW

) 累加金额,

 

adm_dept_codg,

adm_dept_name,

dscg_dept_codg,

dscg_dept_name,

doctor_codg,

doctor_name

FROM

ip_rec t

ORDER BY

t.ipt_no,

t.pat_name

 

 

 

 

 

 

 

 

 

 

 

综合案例实操:

SELECT

pkid,

ipt_no,

pat_name,

pat_sex,

adm_date,

dscg_date,

t.fee,

SUM (fee) OVER (

PARTITION  BY t.ipt_no

ORDER BY t.adm_date

    ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW

) 累加金额,

SUM (fee) OVER (

PARTITION  BY t.ipt_no

ORDER BY t.adm_date

    ROWS BETWEEN 1 PRECEDING and 1 FOLLOWING

) 相邻三条数据累加,

lag(t.dscg_date,1) OVER (PARTITION BY t.ipt_no order by t.adm_date) 上一次出院日期,

    lead(t.dscg_date,1) OVER (PARTITION BY t.ipt_no order by t.adm_date) 下一次入院日期,

adm_dept_codg,

adm_dept_name,

dscg_dept_codg,

dscg_dept_name,

doctor_codg,

doctor_name

FROM

ip_rec t

ORDER BY

t.ipt_no,

t.pat_name

标签:函数,no,SqlServer,dept,开窗,ipt,date,adm,name
来源: https://www.cnblogs.com/shuaihan/p/16411911.html