PostgreSQL 数据库函数

分享 123456789987654321 ⋅ 于 2020-10-23 16:05:00 ⋅ 最后回复由 123456789987654321 2020-10-23 19:16:08 ⋅ 3969 阅读

本人独立承担一个项目,所有业务逻辑全部由sql书写完成,因此分享两个月的总结!

postgresql

https://www.cnblogs.com/hole/p/11699702.html

https://www.yiibai.com/html/postgresql/2013/080443.html

sql函数

SQL UNION 操作符

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
UNION ALL。 操作符用于合并两个或多个 SELECT 语句的结果集。允许重复的值
请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。

Lpad

SQL---Lpad()函数,Rpad()函数,数据库

用    处:用来填充某个字段的查询结果的。比如下面,想查询出frname这个字段,但是我想让查询结果长度固定,不足的用我自己定义的东西去填充,那就用这个函数就好了;这就是一个简单的填充的函数。

eg:
 SELECT lpad(''||max(to_number(substring(zcbh,length(zcbh)-2,3),'999'))+1,3, '0')  FROM sz_zcxx where zcbh like #{str} || '%'

eg:
select LPAD(frname,7,'xo') as '左填充',
                RPAD(frname,8,'xo') as '又填充',
                frname as 不填充
from ent_file where id=11449

CAST

cast函数   数据类型转换
AS:用于分隔两个参数,在AS之前的是要处理的数据,在AS之后是要转换的数据类型。

SELECT CAST('12.5' AS decimal)

    结果是一个整数值:12

CAST (expression AS data_type)
data_type:目标系统所提供的数据类型,包括bigint和sql_variant,不能使用用户定义的数据类型。

使用CAST函数进行数据类型转换时,在下列情况下能够被接受:

(1)两个表达式的数据类型完全相同。
(2)两个表达式可隐性转换。
(3)必须显式转换数据类型。

如果试图进行不可能的转换(例如,将含有字母的 char 表达式转换为 int 类型),SQServer 将显示一条错误信息。
如果转换时没有指定数据类型的长度,则SQServer自动提供长度为30。

decimal(10,2) 是什么意思 在一个表中

 decimal(10,2)中的
“2”表示小数部分的位数,如果插入的值未指定小数部分或者小数部分不足两位则会自动补到2位小数,若插入的值小数部分超过了2为则会发生截断,截取前2位小数。

“10”指的是整数部分加小数部分的总长度,也即插入的数字整数部分不能超过“10-2”位,否则不能成功插入,会报超出范围的错误。

PostgreSQL 数据类型

1.数值类型

名字 存储长度 描述
smallint 2 字节 小范围整数
integer 4 字节 常用的整数
bigint 8 字节 大范围整数
decimal 可变长 用户指定的精度,精确
numeric 可变长 用户指定的精度,精确
real 4 字节 可变精度,不精确
double precision 8 字节 可变精度,不精确
smallserial 2 字节 自增的小范围整数
serial 4 字节 自增整数
bigserial 8 字节 自增的大范围整数

2.货币类型

numeric、int 和 bigint 类型的值可以转换为 money,不建议使用浮点数来处理处理货币类型,因为存在舍入错误的可能性。

名字 存储容量 描述 范围
money 8 字节 货币金额 -92233720368547758.08 到 +92233720368547758.07

offset

偏移,略过几条数据,从这条德厚面开始查询

<! --从第三条开始查询,查询三条数据-->
SELECT * FROM COMPANY LIMIT 3 OFFSET 2;

GROUP BY

根据 某某字段进行分组,过滤。必须配合函数使用

GROUP BY 子句必须放在 WHERE 子句中的条件之后,必须放在 ORDER BY 子句之前。
在 GROUP BY 子句中,你可以对一列或者多列进行分组,但是被分组的列必须存在于列清单中。

SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME ORDER BY NAME DESC;

WITH

WITH 子句可以当做一个为查询而存在的临时表。
WITH 子句多次执行子查询,允许我们在查询中通过它的名称(可能是多次)引用它。
WITH 子句在使用前必须先定义。
##  With子查询
With t AS (
    SELECT * FROM measurement                     -- 子查询的语句,命名为t
) SELECT * FROM t;                                -- 查询子查询

-- output:                                        -- 打印结果与select * from measurement一致
##  With Recursive 循环

with recursive t(X) as (                             -- 定义一个t循环子查询,X是当中的变量
    select 1                                         -- 初始化x为1
    union all                                        -- 每循环拼接下一列
    select x+1 from t where x < 5                    -- 循环列与条件
) select x from t;

--例子  连续 with as 
with dept as (
  select a.code qhdm, a.name as qhmc, b.zzdm, b.zzmc from sys_area_a a 
  left join (select left(qhdm, #[length]) qhdm, zzdm, zzmc from vw_dept_area where qhdm like '#[areaId]%') b on a.code =  b.qhdm 
  where  a.code like '#[areaId]%' and length(a.code) = '#[length]'
), xzq as (select distinct qhdm, qhmc from dept ) 

HAVING

SELECT
FROM
WHERE
GROUP BY
HAVING   #位置
ORDER BY

增删改查

增加

INSERT INTO TABLE_NAME (column1, column2, column3,...columnN)
VALUES (value1, value2, value3,...valueN);
<insert id="addSzZyxxEntity" parameterType="com.gykj.jtsz.domain.SzZyxxEntity" >
insert into  
sz_zyxx   #表名 
(fid,zybh)  #字段名
values  
(#{fid},#{zybh})  #赋值
</insert>

删除

delete from sz_zyxx where fid = #{id};

例如:
<delete id="deleteByPrimaryKey"parameterType="com.gykj.ucenter.domain.SysPjyzconfigKey">
    delete from "sys_pjyzconfig"
    where bxgsdm = #{bxgsdm,jdbcType=VARCHAR}
    and jcxbm = #{jcxbm,jdbcType=VARCHAR}
</delete>

批量删除
   <!--批量删除-->
    <delete id="batchDelete">
        delete from sys_dept where dept_id in
        <foreach item="deptId" collection="array" open="(" separator=","
                 close=")">
            #{deptId}
        </foreach>
    </delete>

递归删除
    <!--递归删除-->
    <delete id="deleteWithRecursive">
        delete from sys_dept where dept_id in (
        WITH RECURSIVE T (dept_id,parent_id) AS (
        SELECT dept_id,parent_id
        FROM sys_dept
        WHERE dept_id = #{value}
        UNION ALL
        SELECT D.dept_id,D.parent_id
        FROM sys_dept D JOIN T ON D.parent_id = CAST(T.dept_id AS VARCHAR(1000))
        )SELECT dept_id FROM T
        )
    </delete>

修改

UPDATE table_name
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];

<update id="UpdateSZDictById" parameterType="com.gykj.jtsz.domain.SzDict">
        update sz_dict set pid=#{pid},dtype=#{dtype},model=#{model},category=#                   {category},key=#{key},value=#{value},level=#{level},pkey=#{pkey},place=#{place}
        where id=#{id}
</update>

<!--根据fid进行修改-->
<update id="updateSzZyxxEntityById"parameterType="com.gykj.jtsz.domain.SzZyxxEntity">
   update sz_zyxx set kpbh=#{kpbh},zzdm=#{zzdm}
   <where>
      <if test="fid != null">
          and fid=#{fid}   #根据什么修改这里就写什么
      </if>
   </where>
</update>

eg:
<update id="updateByPrimaryKey" parameterType="com.gykj.ucenter.domain.SysRole">
update "sys_role"
    set
      role_name = #{roleName,jdbcType=VARCHAR},
      role_sign = #{roleSign,jdbcType=VARCHAR},
    where role_id = #{roleId,jdbcType=VARCHAR}
</update>

查询 EXISTS

WHERE EXISTS (subquery)

括号内同样是一个子查询,如果子查询有返回结果,则EXISTS结果为'TRUE',否则为'FALSE'。
WHERE EXISTS (subquery)

OGNL表达式

trim


trim
    trim标记是一个格式化的标记,可以完成set或者是where标记的功能
    标签属性
prefix:前缀覆盖并增加其内容。也就是给中的sql语句加上前缀;
suffix:后缀覆盖并增加其内容。给包裹的sql语句加上后缀;
prefixOverrides:前缀判断的条件。取消指定的前缀,如where;
suffixOverrides:后缀判断的条件。取消指定的后缀,如and | or.,逗号等。(自动去除后面多余“,”)
例如
<trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
 </trim>      

foreach

foreach
    foreach
    collection      集合或数组的名称
        循环的是数组, 默认为collection=array
        循环的是集合, 默认为collection=list
        循环的是map集合, collection没有默认的map, 直接循环map集合的名称就可以或用@Param指明
        使用@Param指定了参数名, 就要用参数名, 如 : @Param("ids"), collection=ids
        @Param 当我们传入多个参数时,就要用@Param指明, 这个时候它们就被封装成一个map集合, 当然当个参数        也可以封装成map
        item            变量名迭代的每一项   ****
        separator       每次循环的分隔符     ****

        index           索引的属性名, 当迭代的对象为map时, 改值为key
        open            循环开头的字符串
        close           循环结束的字符串
https://blog.csdn.net/weixin_44076273/article/details/103839826
if
    利用 if 实现简单的条件选择
where 和 set
    where 和 set 这两个标签会帮我们智能的处理SQL语句,自动处理一些多余的and或or或 ,
choose(when, otherwise)
    有时候我们有多个选择条件, 但只想选择其中一个, 查询条件满足一个即可, 使用choose即可类似于Java的     switch
sql片段        
    有时候某个sql语句我们会多处用到, 为了增加代码的重用性, 简化代码, 我们需要将其抽取出来, 用的时候直接     调用

例如:
sql
    id 用于引用

include 
     refid      进行调用

bind
    bind元素可以从OGNL表达式中创建一个变量并将其绑定到上下文

常用OGNL表达式

e1 or e2
e1 and e2
e1 == e2,e1 eq e2
e1 != e2,e1 neq e2
e1 lt e2:小于
e1 lte e2:小于等于,其他gt(大于),gte(大于等于)
e1 in e2
e1 not in e2
e1 + e2,e1 * e2,e1/e2,e1 - e2,e1%e2
!e,not e:非,求反

e.method(args)调用对象方法
e.property对象属性值
e1[ e2 ]按索引取值,List,数组和Map
@class@method(args)调用类的静态方法
@class@field调用类的静态字段值

include标签

<include refid="queryCriteria"></include>  #调用前面的方法

定义常量:
sql与include标签
sql标签和include标签一般是一起使用的,sql标签中id属性对应include标签中的refid属性。通过include标签将sql片段和原sql片段进行拼接成一个完整的sql语句进行执行。sql标签可以用来定义可复用的sql代码片段,可以通过include标签包含在其他语句中。
如:
<sql id="user"> id,username,password</sql>

<select id="selectUsers" resultType="map">
  select
    <include refid="user" /> 
  from table
</select>

例如:
 <sql id="Base_Column_List">
    id, user_id, username, "operation", "time", "method", params, ip, gmt_create, "module", 
    "type", "result", error, remark
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from "sys_log"
    where id = #{id,jdbcType=VARCHAR}
  </select>

mapper

<mapper namespace="com.gykj.ucenter.dao.SysLogDao">  命名空间
                 基础命名               映射实体类
  <resultMap id="BaseResultMap" type="com.gykj.ucenter.domain.SysLog">
    <id column="id" jdbcType="VARCHAR" property="id" />  主键id
                    数据库字段        类型                 实体字段
    <result column="user_id" jdbcType="VARCHAR" property="userId" />
    <result column="username" jdbcType="VARCHAR" property="username" />
    <result column="operation" jdbcType="VARCHAR" property="operation" />
    <result column="time" jdbcType="INTEGER" property="time" />
    <result column="method" jdbcType="VARCHAR" property="method" />
    <result column="params" jdbcType="VARCHAR" property="params" />
    <result column="ip" jdbcType="VARCHAR" property="ip" />
    <result column="gmt_create" jdbcType="TIMESTAMP" property="gmtCreate" />
    <result column="module" jdbcType="VARCHAR" property="module" />
    <result column="type" jdbcType="VARCHAR" property="type" />
    <result column="result" jdbcType="INTEGER" property="result" />
    <result column="error" jdbcType="VARCHAR" property="error" />
    <result column="remark" jdbcType="VARCHAR" property="remark" />
  </resultMap>

sql

postgressql
https://www.runoob.com/postgresql/postgresql-with.html
        https://www.cnblogs.com/geo-will/p/9535421.html

        ## SQL UNION 操作符

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。

请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。

**注释:**默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。

COALESCE:返回传入的参数中第一个非null的值  如果所有的表达式都为空值,则返回NULL。

SQL---Lpad()函数,Rpad()函数,数据库

用    处:这是mysql的两个函数,用来填充某个字段的查询结果的。比如下面,想查询出frname这个字段,但是我想让查询结果长度固定,不足的用我自己定义的东西去填充,那就用这个函数就好了;这就是一个简单的填充的函数。

select LPAD(frname,7,'xo') as '左填充',
                RPAD(frname,8,'xo') as '又填充',
                frname as 不填充
from ent_file where id=11449

# postgresql

#####  @Column(name = "skf",alias = "收款方")

 # @Column 字段  alias  别名

 @Table(name = "sz_xmht")  表名

@Column(alias = "变动日期")

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "GMT+8")

@DateTimeFormat(pattern = "yyyy-MM-dd")

decimal(10,2)

decimal(10,2) 是什么意思 在一个表中

decimal(10,2)中的“2”表示小数部分的位数,如果插入的值未指定小数部分或者小数部分不足两位则会自动补到2位小数,若插入的值小数部分超过了2为则会发生截断,截取前2位小数。

“10”指的是整数部分加小数部分的总长度,也即插入的数字整数部分不能超过“10-2”位,否则不能成功插入,会报超出范围的错误。

cast()函数

cast函数

SELECT CAST('12.5' AS decimal)

​    结果是一个整数值:12

**一、语法:**

CAST (expression AS data_type)

**参数说明:**

**expression**:任何有效的SQServer表达式。

**AS**:用于分隔两个参数,在AS之前的是要处理的数据,在AS之后是要转换的数据类型。

**data_type**:目标系统所提供的数据类型,包括bigint和sql_variant,不能使用用户定义的数据类型。

**使用CAST函数进行数据类型转换时,在下列情况下能够被接受:**

(1)两个表达式的数据类型完全相同。
(2)两个表达式可隐性转换。
(3)必须显式转换数据类型。

**如果试图进行不可能的转换(例如,将含有字母的 char 表达式转换为 int 类型),SQServer 将显示一条错误信息。**

**如果转换时没有指定数据类型的长度,则SQServer自动提供长度为30。**

sql函数

||

||
连接符

in

regexp_split_to_table 函数

regexp_split_to_array 函数

这两个函数都是用来将字符串转换成格式化数据,一个是转换成结果集,一个是转换成数组。

SELECT
     <include refid="Base_Column_List" />
FROM
    sys_role
WHERE
    role_id IN (
                SELECT                      ****这里的roles是一个集合,查询到的结果是一个范围
                    regexp_split_to_table( roles, ',' )  
                FROM
                    sys_role    
                WHERE
                    role_id = #{roleId}
                )

COALESCE()函数

这个函数主要用来进行空值处理
COALESCE ( expression,value1,value2……,valuen) 
COALESCE()函数的第一个参数expression为待检测的表达式,而其后的参数个数不定。
COALESCE()函数将会返回    包括expression在内的所有参数中的第一个非空表达式。
如果expression不为空值则返回expression;否则判断value1是否是空值,
如果value1不为空值则返回value1;否则判断value2是否是空值,
如果value2不为空值则返回value3;
……以此类推,如果所有的表达式都为空值,则返回NULL。

case when then

case when b.parent_id ISNULL then 0 else 1 end

date_trunc()

https://blog.csdn.net/liguangxianbin/article/details/80166574?utm_source=blogxgwz4

select date_trunc('month',now()) +interval '12 h';      
//每月1号 12点      

select date_trunc('month',now()) + interval '15 d 9 h 30 min';      
//每月15号9点半      

select date_trunc('day',now()) + interval '9 h';        
//每天9点      

select date_trunc('day',now()) + interval '7 d';        
//每周的今天     
select date_trunc('weak',now())  + interval '1d 1minute';       
//每周的周二第一分钟     

select date_trunc('h',now()) + interval '30 minute';        
//每小时       

select date_trunc('minute',now()) + interval '30 second';       
//每分钟       
select date_trunc('minute',now()) + interval '30 minute 30 second';     
//每30分钟         

select date_trunc('quarter',now()) + interval '15 d 15 h 15 minute 30 second';      
//本季度的第15天,15小时 15分 30秒     
select date_trunc('quarter',now() ) - interval '1 h';       
//每个季度最后一天的晚上11点        
select date_trunc('quarter',now() + interval '3 month') - interval '1 h';       
//每个季度的最后一天的晚上的11点(从下个季度开始算起).

OGNL表达式

https://mybatis.org/mybatis-3/zh/dynamic-sql.html

sql类型转换

CAST 和 CONVERT
将某种数据类型的表达式显式转换为另一种数据类型。CAST 和 CONVERT 提供相似的功能。
语法
使用 CAST:
CAST ( expression AS data_type )
使用 CONVERT:
CONVERT (data_type[(length)], expression [, style])

取整

【四舍五入取整截取】

select round(54.56,0)

 【向下取整截取】

SELECT FLOOR(54.56)

 【向上取整截取】

 SELECT   CEILING(13.15)

--MSSQL取整函数的使用

--两个整数相除将截断小数部分 
select 3/4,4/3,5/3 
--结果 0,1,1 

子查询

select a.code, a.name, b.hs, c.gfs from sys_area a
left join (select area_id, count(*) hs from qc_jtcy group by area_id) b on a.code = b.area_id
left join (select area_id, sum(fpze) gfs from cg_jjzz_gqfp group by area_id) c on a.code = b.area_id
where length(a.code)>12
order by b.hs, c.gfs

值为0返回null

case when zhs =0 or zhs =null then null else  round(zgs/zhs) end as hjgfs   ,
             case when zrs =0 or zrs =null then null else round(zgs/zrs) end as rjgfs 

研究

SELECT lpad(''||max(to_number(substring(zcbh,length(zcbh)-2,3),'999'))+1,3, '0')  FROM sz_zcxx where zcbh like #{str} || '%'
select ROW_NUMBER()OVER()as xh, * from hzb_gd_xhdcqk!{#[sjly]}
where f_xzqdm like '#[xzqdm]%' 
and length(f_xzqdm)<=case '#[tjjb]' when '省' then 2 when '市' then 4 when '县' then 6 when '乡' then 9 when '村' then 12 end
and f_fromdate BETWEEN '#[sjnf]-01-01' and '#[sjnf]-12-30'
order by f_xzqdm
···
select ROW_NUMBER()OVER()as xh,* from hzb_ydmj!{#[sjly]}
where f_xzqdm like '#[xzqdm]%' 
and length(f_xzqdm)<=case '#[tjjb]' when '省' then 2 when '市' then 4 when '县' then 6 when '乡' then 9 when '村' then 12 end
and f_fromdate BETWEEN '#[sjnf]-01-01' and '#[sjnf]-12-30'
order by f_xzqdm

substring

SUBSTR (str, pos, len)**      字符串str 。 从pos开始,到len
1、left(name,4)截取左边的4个字符
列:
SELECT LEFT(201809,4) 年
结果:2018

2、right(name,2)截取右边的2个字符
SELECT RIGHT(201809,2) 月份
结果:09

3、SUBSTRING(name,5,3) 截取name这个字段 从第五个字符开始 只截取之后的3个字符
SELECT SUBSTRING('成都融资事业部',5,3)
结果:事业部

4、SUBSTRING(name,3) 截取name这个字段 从第三个字符开始,之后的所有个字符
SELECT SUBSTRING('成都融资事业部',3)
结果:融资事业部

5、SUBSTRING(name, -4) 截取name这个字段的第 4 个字符位置(倒数)开始取,直到结束
SELECT SUBSTRING('成都融资事业部',-4)
结果:资事业部

6、SUBSTRING(name, -4,2) 截取name这个字段的第 4 个字符位置(倒数)开始取,只截取之后的2个字符
SELECT SUBSTRING('成都融资事业部',-4,2)
结果:资事
注意:我们注意到在函数 substring(str,pos, len)中, pos 可以是负值,但 len 不能取负值。

7、substring_index('www.baidu.com', '.', 2) 截取第二个 '.' 之前的所有字符
SELECT substring_index('www.baidu.com', '.', 2)
结果:www.baidu

8、substring_index('www.baidu.com', '.', -2) 截取第二个 '.' (倒数)之后的所有字符
SELECT substring_index('www.baidu.com', '.', -2)
结果:baidu.com

9、SUBSTR(name, 1, CHAR_LENGTH(name)-3) 截取name字段,取除name字段后三位的所有字符
SELECT SUBSTR('成都融资事业部', 1, CHAR_LENGTH('成都融资事业部')-3)
结果:成都融资

distinct

字段去重
select distinct zcname from dfs_zc where zcname like '%[keyword]%' limit 5 offset 0

offset limit

limit y 分句表示: 读取 y 条数据

limit x, y 分句表示: 跳过 x 条数据,读取 y 条数据

limit y offset x 分句表示: 跳过 x 条数据,读取 y 条数据

nulls last nulls first

--null值在前
select * from tablename order by id nulls first;

--null值在后
select * from tablename order by id nulls last;

--null在前配合desc使用
select * from tablename order by id desc nulls first;

--null在后配合desc使用
select * from tablename order by id desc nulls last;

举例:
null值在后,先按照count1降序排列,count1相同再按照count2降序排列

order by count1 desc nulls last, count2  desc nulls last;

to_char(number)函数

to_char(待转换值,转换格式);  to_char(b.jzrq,'yyyy-MM-dd')

to_number

select sum(to_number(mj,9999.99)) as amountmj
 from table group by area

其中9999.99就是不管是mj字段的值还是amountmj的值不能超过9999.99,且保留两位小数。

字段大小写 用“ ”

select  grggfs,jtggfs,  area_id as "areaId",

pg数据库实现mysql的group_concat

自定义函数

DROP AGGREGATE group_concat(anyelement);
CREATE AGGREGATE group_concat(anyelement)
(
sfunc = array_append, -- 每行的操作函数,将本行append到数组里
stype = anyarray, -- 聚集后返回数组类型
initcond = '{}' -- 初始化空数组
);

函数使用

select  groupconcat(a,',') from  xxxx

<> 不等于

where code like '46%'  and code<>'46'    
<> 类似于 !=    

sql函数

select j.gqmc, m.gqlb,sum(m.gfs) as gfs,sum(m.cyrs) as cyrs,COALESCE(round(sum(m.gfs)/sum(case when m.cyrs = 0 then NULL else m.cyrs end )),0) as mrzg ,
                concat(( cast( (sum(m.gfs)/COALESCE(sum(s.grggfs),1)) as decimal(4,2) ))*100,'%')  as gqzb 
        from cg_jjzz_gqfp_mx m 
                inner join  cg_jjzzgqlb j on m.gqlb =j.gqdm and m.area_id = j.area_id
                inner join  cg_jjzz_gqfp  s on m.area_id = s.area_id
        where m.area_id like  '#[areaId]%' and length(m.area_id) >= 12 
                group by  m.gqlb        ,j.gqmc

ROW_NUMBER() OVER()函数

https://blog.csdn.net/qq_25221835/article/details/82762416
语法格式:row_number() over(partition by 分组列 order by 排序列 desc)

row_number() over()分组排序功能:
在使用 row_number() over()函数时候,over()里头的分组以及排序的执行晚于 where 、group by、  order by 的执行。

例一:
一次排序:对查询结果进行排序(无分组)
select id,name,age,salary,row_number()over(order by salary desc) rn
from TEST_ROW_NUMBER_OVER t

进一步排序:根据id分组排序
select id,name,age,salary,row_number()over(partition by id order by salary desc) rank
from TEST_ROW_NUMBER_OVER t

再一次排序:找出每一组中序号为一的数据
select * from(select id,name,age,salary,row_number()over(partition by id order by salary desc) rank
from TEST_ROW_NUMBER_OVER t)
where rank <2

between and

with dept as (
  select a.code qhdm, a.name as qhmc, b.zzdm, b.zzmc from sys_area a 
  join (select left(qhdm, #[length]) qhdm, zzdm, zzmc from vw_dept_area where qhdm like '#[areaId]%') b on a.code =  b.qhdm 
  where  a.code like '#[areaId]%' and length(a.code) = '#[length]'
)

select sum(skje) zsr
from sz_zjsk z
join dept b on z.zzdm =  b.zzdm and z.create_time between '#[year]-01-01' and '#[year]-12-31 23:59:59'

排序函数rank() row_number()

https://www.xin3721.com/sqlTech/mobil16812.html
-----------------------------------------------
--1.rank()  
RANK()函数,顾名思义排名函数,可以对某一个字段进行排名,这里和ROW_NUMBER()有什么不一样呢?
ROW_NUMBER()是排序,当存在相同成绩的学生时,ROW_NUMBER()会依次进行排序,他们序号不相同,而Rank()则不一样。如果出现相同的,他们的排名是一样的。下面看例子:

SELECT RANK() OVER (ORDER BY SCORE DESC) AS [RANK],*
FROM Scores;

--2.row_number()
语法格式:row_number() over(partition by 分组列 order by 排序列 desc)

ROW_NUMBER()函数作用就是将SELECT查询到的数据进行排序,每一条数据加一个序号,
他不能用做于学生成绩的排名,一般多用于分页查询,比如查询前10个 查询10-100个学生。
1.1 对学生成绩排序示例
SELECT ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS [RANK],*
FROM Scores; 
--1  2  3  4  5 
--85 85 80 74 70 
SELECT RANK() OVER (ORDER BY SCORE DESC) AS [RANK],*
FROM Scores; 
--1  1  3  4  5 
--85 85 80 74 70 

1.2 获取第2名的成绩信息
SELECT * FROM (
SELECT ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS [RANK],*
FROM Scores
) t WHERE t.RANK=2;

--3.DENSE_RANK()
DENSE_RANK()函数也是排名函数,和RANK()功能相似,也是对字段进行排名,那它和RANK()到底有什么不同那?特别是对于有成绩相同的情况,
DENSE_RANK()排名是连续的,
RANK()是跳跃的排名,      --一般情况下用的排名函数就是RANK() 
SELECT 
RANK() OVER (ORDER BY SCORE DESC) AS [RANK],*
FROM Scores;
--1  1  3  4  5 
--85 85 80 74 70 

SELECT 
DENSE_RANK() OVER (ORDER BY SCORE DESC) AS [RANK],*
FROM Scores; 
--1  1  2  3  4 
--85 85 80 74 70

--4、NTILE()
  NTILE()函数是将有序分区中的行分发到指定数目的组中,各个组有编号,编号从1开始,就像我们说的'分区'一样 ,分为几个区,一个区会有多少个。

NULLS LAST

null值往后排
版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海汼部落-123456789987654321,http://hainiubl.com/topics/75346
本帖已被设为精华帖!
本帖由 青牛 于 4年前 加精
回复数量: 2
  • 青牛 海汼部落创始人,80后程序员一枚,曾就职于金山,喜欢倒腾技术做产品
    2020-10-23 18:29:08

    小伙真的很努力,以后指定有发展

  • 123456789987654321 奶牛(野牛的大哥)
    2020-10-23 19:16:08

    @青牛 嘻嘻,谢谢何老师

暂无评论~~
  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,可用Emoji的自动补全, 在输入的时候只需要 ":" 就可以自动提示了 :metal: :point_right: 表情列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif,教程
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
Ctrl+Enter