SQL使用技巧

news2025/1/24 9:30:48

1、行列转换:

  decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值);

  select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值

  sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1

  例如:

  变量1=10,变量2=20

  则sign(变量1-变量2)返回-1,decode解码结果为“变量1”,达到了取较小值的目的。

举例:查询emp表中的每个部门的人数?

SELECT sum(decode(deptno,10,1,0)) as 部门10,
            sum(decode(deptno,20,1,0)) as 部门20,
            sum(decode(deptno,30,1,0)) as 部门30 from emp

复制

      做个对比:select deptno,count(deptno) from emp group by deptno

2、递归查询的优化

   lpad/rpad( string, padded_length, [ pad_string ] )

   解释:字符不够的时候向左或者向右填充。

   例如:

SQL> select lpad('abcde',10,'x') from dual;
      LPAD('ABCDE',10,'X')
      xxxxxabcde
SELECT ID, FATHER_ID, NAME, CONNECT_BY_ISLEAF LEAF   
FROM T_TREE   
START WITH FATHER_ID = 0   
CONNECT BY PRIOR ID = FATHER_ID;  

复制

解释:CONNECT_BY_ISLEAF 判断该行记录是否为叶子节点,如果是返回1,否则返回0

          START WITH FATHER_ID = 0 规定哪一条记录为根节点

          CONNECT BY PRIOR ID = FATHER_ID 判断此节点的父节点是哪一条记录

例子:

 SELECT LPAD(MENU_NAME,
            LENGTHB(MENU_NAME) + LEVEL,
            DECODE(CONNECT_BY_ISLEAF, 1, ' | ', '+'))
  FROM MENU
  START WITH PID = '0'
  CONNECT BY PRIOR ID = PID;

复制

3、利用分析函数排序和去重

http://blog.csdn.net/haiross/article/details/15336313#comments

分析函数是什么? 分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计值。

分析函数和聚合函数的不同之处是什么? 普通的聚合函数用group by分组,每个分组返回一个统计值,返回的字段名只能是分组名。而分析函数采用partition by分组,并且每组每行都可以返回一个统计值,返回的字段名可以是每个字段,因为是对应到记录的,所以没有关系。

分析函数的形式 分析函数带有一个开窗函数over(),包含三个分析子句:分组(partition by), 排序(order by), 窗口(rows) ,他们的使用形式如下:over(partition by xxx order by yyy rows between zzz)

开窗函数over()包含三个分析子句:分组子句(partition by), 排序子句(order by), 窗口子句(rows) 窗口就是分析函数分析时要处理的数据范围,就拿sum来说,它是sum窗口中的记录而不是整个分组中的记录,因此我们在想得到某个栏位的累计值时,我们需要把窗口指定到该分组中的第一行数据到当前行, 如果你指定该窗口从该分组中的第一行到最后一行,那么该组中的每一个sum值都会一样,即整个组的总和。

OVER(PARTITION BY DEPTNO ORDER BY ENAME ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW):当前组第一行到当前行的汇总
OVER(PARTITION BY DEPTNO ORDER BY ENAME ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING):当前行到最后一行的汇总

OVER(PARTITION BY DEPTNO ORDER BY ENAME ROWS BETWEEN 1 PRECEDING AND CURRENT ROW):当前行的上一行(rownum-1)到当前行的汇总

OVER(PARTITION BY DEPTNO ORDER BY ENAME ROWS BETWEEN 1 PRECEDING AND 2 FOLLOWING):当前行的上一行(rownum-1)到下两行(rownum+2)的汇总

复制

而无论是否省略分组子句,如下结论都是成立的:

 1、窗口子句不能单独出现,必须有order by子句时才能出现。

 2、当省略窗口子句时:     a) 如果存在order by则默认的窗口是unbounded preceding and current row  --当前组的第一行到当前行,即在当前组中,第一行到当前行,这里强调一下,如果partition by字段和order by 字段一样的话,这个order by不生效,相当于省略了order by

    b) 如果同时省略order by则默认的窗口是unbounded preceding and unbounded following  --整个组

两个order by的执行时机

分析函数(以及与其配合的开窗函数over())是在整个sql查询结束后(sql语句中的order by的执行比较特殊)再进行的操作, 也就是说sql语句中的order by也会影响分析函数的执行结果:

    a) 两者一致:如果sql语句中的order by满足与分析函数配合的开窗函数over()分析时要求的排序,即sql语句中的order by子句里的内容和开窗函数over()中的order by子句里的内容一样,那么sql语句中的排序将先执行,分析函数在分析时就不必再排序;     b) 两者不一致:如果sql语句中的order by不满足与分析函数配合的开窗函数over()分析时要求的排序,即sql语句中的order by子句里的内容和开窗函数over()中的order by子句里的内容不一样,那么sql语句中的排序将最后在分析函数分析结束后执行排序。

常用的分析函数:

  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 ...) lag函数可以在一次查询中取出同一字段的前n行的数据

  12、lead() over(partition by ... order by ...) lead函数可以在一次查询中取出同一字段的后n行的值

lag(arg1,arg2,arg3) 第一个参数是列名, 第二个参数是偏移的offset, 第三个参数是超出记录窗口时的默认值。

select id,name,lag(name,1,0) over(order by id) from kkk; 

 例子:select ename,deptno,sal,sum(sal) over(partition by deptno order by ename) as A from emp

去重:

  1、利用rowid的唯一性查询或删除重复数据

   select ROWNUM,ROWID,d1.* from dept2 d1 where d1.rowid=(select min(d2.rowid) from dept2 d2 where d2.deptno=d1.deptno);

复制

2、给定重复行序号并去重

SELECT FWZL
    FROM (SELECT FWZL,
                 ROW_NUMBER() OVER(PARTITION BY FWZL ORDER BY ID DESC) RN
            FROM T_FWXX) F

                       WHERE F.RN = 1

复制

 4、求占比、小计和总计

      分析函数RATIO_TO_REPORT 用来计算当前记录的指标expr占开窗函数over中包含记录的所有同一指标的百分比. 这里如果开窗函数的统计结果为null或者为0,就是说占用比率的被除数为0或者为null, 则得到的结果也为0. 开窗条件query_partition_clause决定被除数的值, 如果用户忽略了这个条件, 则计算查询结果中所有记录的汇总值. 用户不能使用其他分析函数或者ratio_to_report作为分析函数ratio_to_report的参数expr, 也就是说这个函数

 百分比(求这个字段值占整组的百分比):select deptno,ename,empno,round(RATIO_TO_REPORT(sal) OVER(PARTITION BY deptno)*100,1) 百分比 from emp

rollup()与cube():排列组合分组

1)、group by rollup(a, b, c): 首先会对(a、b、c)进行group by, 然后再对(a、b)进行group by, 其后再对(a)进行group by, 最后对全表进行汇总操作。

2)、group by cube(a, b, c): 则首先会对(a、b、c)进行group by, 然后依次是(a、b),(a、c),(a),(b、c),(b),(c), 最后对全表进行汇总操作。

ROLLUP,是GROUP BY子句的一种扩展,可以为每个分组返回小计记录以及为所有分组返回总计记录。

CUBE,也是GROUP BY子句的一种扩展,可以返回每一个列组合的小计记录,同时在末尾加上总计记录。

求每个分组的小计和总计:select deptno,sal,sum(sal) from emp group by rollup(deptno,sal)

求每一个列的组合的小计记录:select deptno,sum(sal) from emp group by cube(deptno,sal)

聚合函数(within group语法):

select rank(1500) within group (order by sal desc) "rank of 1500" from emp;

    解释:如果存在一条记录,这条记录的salary字段值为1500。那么将该条记录插入emp表中后,按照sal字段降序排列后,该条记录的序号为多少?

可以使用within group关键字的函数有rank,dense_rank,PERCENT_RANK,PERCENTILE_CONT,PERCENTILE_DISC等

 5、单条记录插入多表

      原理:利用一个insert all 语法:insert all when .. then

INSERT ALL WHEN LOCALE = 1 THEN INTO EMPLOYEE1(ID, LOCALE, NAME, AGE, GENDER, CODE) VALUES (ID, LOCALE, NAME, AGE, GENDER, CODE)

                  WHEN LOCALE = 32 THEN INTO EMPLOYEE2(ID, LOCALE, NAME, AGE, GENDER, CODE) VALUES(ID, LOCALE, NAME, AGE, GENDER, CODE)

insert all into table values()

              into  table values()

 6、Merge的使用

 解释:DML语句,适用于批量处理

   MERGE INTO table_name alias1    USING (table|view|sub_query) alias2    ON (join condition)    WHEN MATCHED THEN    UPDATE table_name   SET col1 = col_val1,    col2 = col2_val where 条件   WHEN NOT MATCHED THEN    INSERT (column_list) VALUES (column_values) where 条件;

MERGE INTO EMPLOYEE E

USING (SELECT * FROM EMPLOYEE1) E1

ON (E.NAME = E1.NAME)

WHEN MATCHED THEN

    UPDATE SET E.CODE = E1.CODE, E.AGE = E1.AGE

WHEN NOT MATCHED THEN

   INSERT  (E.ID, E.LOCALE, E.NAME, E.AGE, E.GENDER, E.CODE) VALUES(E1.ID, E1.LOCALE, E1.NAME, E1.AGE, E1.GENDER, E1.CODE);

备注:对两张表的两个字段相匹配,如果匹配上了就做更新操作,否则就做插入操作。

 7、KEEP的使用

     keep是Oracle下的另一个分析函数,他的用法不同于通过over关键字指定的分析函数,可以用于这样一种场合下:取同一个分组下以某个字段排序后,对指定字段取最小或最大的那个值。

  一般写法是 MIN [ MAX ] (A) KEEP(DENSE_RANK FIRST [ LAST ] ORDER BY B),这里引用别人说的明的解释一下:

DENSE_RANK

功能描述:根据ORDER BY子句中表达式的值,从查询返回的每一行,计算它们与其它行的相对位置。组内的数据按ORDER BY子句排序,然后给每一行赋一个号,从而形成一个序列,该序列从1开始,往后累加。每次ORDER BY表达式的值发生变化时,该序列也随之增加。有同样值的行得到同样的数字序号(认为null时相等的)。密集的序列返回的时没有间隔的数。

FIRST

功能描述:从DENSE_RANK返回的集合中取出排在最前面的一个值的行(可能多行,因为值可能相等),因此完整的语法需要在开始处加上一个集合函数以从中取出记录。

LAST

功能描述:从DENSE_RANK返回的集合中取出排在最后面的一个值的行(可能多行,因为值可能相等),因此完整的语法需要在开始处加上一个集合函数以从中取出记录。

所以默认排序下,FIRST可以理解是取小值,LAST取大值。而前面的MIN或者MAX则是在KEEP的结果集中取某一字段的最大值或最小值。

  keep和普通分析函数的区别:普通的分析函数只是列出分组后的记录,而对每一个组的记录进行统计分析。

                            keep对分组内的函数通过order by和max(),min()选取某个字段的值。可以理解成这里的keep就是sum() groud by deptno 前的sum()那样

  实例:取出各个部门薪资最高的员工编号

  1、select deptno,empno,sal,max(empno) keep(dense_rank first order by sal desc) over(partition by deptno) from emp2

  2、select deptno,max(empno) keep(dense_rank first order by sal desc) from emp2 group by deptno 

        解释:按deptno分组,再对分组中的sal降序,取出第一个sal的员工号

8、SQL查询正则表达式的使用

  ORACLE中的支持正则表达式的函数主要有下面四个: 1,REGEXP_LIKE :与LIKE的功能相似

    select * from emp where regexp_like(empno,'7[0-9]{2}9') 2,REGEXP_INSTR :与INSTR的功能相似

REGEXP_INSTR

6个参数

第一个是输入的字符串

第二个是正则表达式

第三个是标识从第几个字符开始正则表达式匹配。(默认为1)

第四个是标识第几个匹配组。(默认为1)

第五个是指定返回值的类型,如果该参数为0,则返回值为匹配位置的第一个字符,如果该值为非0则返回匹配值的最后一个位置。

第六个是是取值范围:

i:大小写不敏感;

c:大小写敏感;

n:点号 . 不匹配换行符号;

m:多行模式;

x:扩展模式,忽略正则表达式中的空白字符。

    SELECT REGEXP_INSTR(a,'[0-9]+') AS A FROM test_reg_substr;

3,REGEXP_SUBSTR :与SUBSTR的功能相似

REGEXP_SUBSTR函数格式如下:

   function REGEXP_SUBSTR(String, pattern, position, occurrence, modifier) __srcstr     :需要进行正则处理的字符串 __pattern    :进行匹配的正则表达式 __position   :起始位置,从第几个字符开始正则表达式匹配(默认为1) __occurrence :标识第几个匹配组,默认为1 __modifier   :模式('i'不区分大小写进行检索;'c'区分大小写进行检索。默认为'c'。)

  1. --1、查询使用正则分割后的第一个值,也就是34  
  2. SELECT REGEXP_SUBSTR('34,56,-23','[^,]+',1,1,'i') AS STR FROM DUAL;  
  3. --结果是:34   
  4. --2、查询使用正则分割后的最后一个值,也就是-23  
  5. SELECT REGEXP_SUBSTR('34,56,-23','[^,]+',1,3,'i') AS STR FROM DUAL;  
  6. --结果是:-23  

4,REGEXP_REPLACE :与REPLACE的功能相似

9、常见函数

TRUNC:截取函数

EXTRACT:用于从一个date或者interval类型中截取到特定的部分

NVL

DECODE

length:字符长度

lengthb:字节长度

ASCII

INITCAP:首字母大写

SOUNDEX:返回由四个字符组成的代码 (SOUNDEX) 以评估两个字符串的相似性

MONTHS_BETWEEN

ADD_MONTHS

NEXT_DAY

LAST_DAY

ROUND:函数用于把数值字段舍入为指定的小数位数

10、分页函数

--普通写法

SELECT AA.FWZL, AA.FWTYBH
  FROM (SELECT A.FWZL, A.FWTYBH, ROWNUM RN
          FROM (SELECT F.FWZL, F.FWTYBH FROM FW F ORDER BY F.FWTYBH DESC) A
         WHERE ROWNUM <= 120020) AA
 WHERE AA.RN > 120000;

复制

--rowid写法

SELECT /*+ ROWID(FW) */ FW.FWZL, FW.FWTYBH
   FROM FW FW,
        (SELECT AA.RID, AA.RN
           FROM (SELECT A.RID, ROWNUM RN
                  FROM (SELECT /*+ index(F IDX_FW_FWTYBH) */
                         ROWID RID
                          FROM FW F
                          ORDER BY F.FWTYBH DESC) A
                 WHERE ROWNUM <= 120020) AA
          WHERE AA.RN > 120000) B
  WHERE FW.ROWID = B.RID;

复制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/632351.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中间件定义

中间件(middleware)是基础软件的一大类&#xff0c;属于可复用的软件范畴。中间件在操作系统软件&#xff0c;网络和数据库之上&#xff0c;应用软件之下&#xff0c;总的作用是为处于自己上层的应用软件提供运行于开发的环境&#xff0c;帮助用户灵活、高效的开发和集成复杂的…

CTFHub | 读取源代码

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习&#xff0c;实训平台。提供优质的赛事及学习服务&#xff0c;拥有完善的题目环境及配套 writeup &#xff0c;降低 CTF 学习入门门槛&#xff0c;快速帮助选手成长&#xff0c;跟随主流比赛潮流。 0x01 题目描述…

互斥量实现原理探究

文章目录 1. 如何实现线程的加锁和解锁2. 封装一个锁3. 可重入和线程安全3.1 可重入与线程安全联系3.2 可重入与线程安全区别 4. 常见锁概念4.1 死锁4.2 代码实现4.3 死锁四个必要条件 1. 如何实现线程的加锁和解锁 经过上一篇文章的例子&#xff0c;大家已经意识到单纯的 i 或…

快速在linux上配置python3.x的环境以及可能报错的解决方案(python其它版本可同样方式安装)

一. linux安装python3.x 下面案例是安装python3.9 步骤&#xff0c;也可以指定其他版本安装 步骤1&#xff1a;安装系统依赖&#xff08;重要&#xff09; 这一步不执行&#xff0c;后面各种错误。 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sql…

【Python小技巧】更换python版本解决了plt.show()不显示图像的问题

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、df.plot() 显示不出图像&#xff1f;二、换个python版本问题解决总结 前言 from matplotlib import pyplot as plt kdata.plot(xtrade_time, y[close,BOLL…

ThreadPoolExecutor线程池

文章目录 一、ThreadPool线程池状态二、ThreadPoolExecutor构造方法三、Executors3.1 固定大小线程池3.2 带缓冲线程池3.3 单线程线程池 四、ThreadPoolExecutor4.1 execute(Runnable task)方法使用4.2 submit()方法4.3 invokeAll()4.4 invokeAny()4.5 shutdown()4.6 shutdownN…

SpringBoot-Actuator健康检查-打印日志改造应用策略模式+简单工厂

类图 包结构 代码实例 pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apac…

【MySQL 数据库】10、MySQL 的触发器

MySQL 的触发器 零、存储函数一、触发器二、触发器的使用和语法 零、存储函数 存储函数是有返回值的存储过程存储函数的参数只能是 IN 类型 characteristic 说明&#xff1a; ① DETERMINISTIC&#xff1a;相同的输入参数总是产生相同的结果 ② NO SQL &#xff1a;不包含 SQL…

【PCB专题】案例:绕等长怎么直接以颜色区分看出是否绕好

PCB上对于时序的处理,在板卡上实际我们是通过绕等长的手段。做为一个合格的Layout工程师,等长的处理是不可或缺的技能。 一般来说,在绕等长的时候我们可以使用Delay Tune命令来改变走线的长度,然后通过规则管理器中分析看看哪根线长哪根线短。 但是在实际工作中,很可能绕着…

【AI绘画】为小白准备的最简单本地部署安装使用教程——webui启动器

什么是AI绘画&#xff1f; ai绘画&#xff0c;也叫“ai作画”、“人工智能绘画”&#xff0c;即通过 AI 生成技术得到画作或图片。ai作画由来已久&#xff0c;有许多创作ai绘画作品的方式&#xff0c;包括基于规则的图像生成算法、深度学习算法。最近火爆全网的是通过文本描述…

悟道3.0全面开源!LeCun VS Max 智源大会最新演讲

夕小瑶科技说 原创 作者 | 小戏 2023 年智源大会如期召开&#xff01; 这场汇集了 Geoffery Hinton、Yann LeCun、姚期智、Joseph Sifakis、Sam Altman、Russell 等一众几乎是 AI 领域学界业界“半壁江山”的大佬们的学术盛会&#xff0c;聚焦 AI 领域的前沿问题&#xff0c…

【EasyX】实时时钟

目录 实时时钟1. 绘制静态秒针2. 秒针的转动3. 根据实际时间转动4. 添加时针和分针5. 添加表盘刻度 实时时钟 本博客介绍利用EasyX实现一个实时钟表的小程序&#xff0c;同时学习时间函数的使用。 本文源码可从github获取 1. 绘制静态秒针 第一步定义钟表的中心坐标center&a…

使用Python绘制粽子消消乐,素描图(优化版,正常/漫画/写实风格),词云图,字符画图及提取轮廓

使用Python绘制粽子消消乐&#xff0c;素描图&#xff08;优化版&#xff0c;正常/漫画/写实风格&#xff09;&#xff0c;词云图&#xff0c;字符画图及提取轮廓 1. 效果图2. 源码2.1 素描图源码2.2 [优化版&#xff1a;制作不同风格的素描图&#xff08;正常&#xff0c;漫画…

String的理解

1.号 1. 1 号连接符的实现原理 StringBuilder&#xff08;或者StringBuffer&#xff09;的apend方法拼接&#xff0c;然后toString方法返回新的字符串 1.2 号的特殊情况 1.2.1 当""两端均为编译期确定的字符串常量时&#xff0c;编译器会进行相应的优化&#xf…

springboot项目外卖管理 day05-新增与删除套餐

文章目录 一、新增菜品1.1、需求分析1.2、数据模型setmealsetmeal_dish 1.3、代码开发-梳理交互过程1.3.1、下拉框展示1.3.2、菜品窗口展示1.3.3、新增套餐 2、套餐分页查询 一、新增菜品 1.1、需求分析 套餐就是菜品的集合。 后台系统中可以管理套餐信息&#xff0c;通过新…

solr快速上手:常用查询语法(八)

0. 引言 solr作为搜索引擎&#xff0c;就像我们使用mysql一样&#xff0c;在日常业务中&#xff0c;更多接触的则是各类操作语法&#xff0c;所以今天&#xff0c;我们再来学习solr的常用查询语法&#xff0c;为大家在工作中最基本的solr查询打下基础。 solr快速上手&#xff…

ia write 自定义 导出模板

https://github.com/yangyang5214/github-plus.iatemplate 使用了点个 star 吧&#xff09; 在原有的 GitHub 模板基础上&#xff0c;增加了 封面页面和页脚。 封面页面 展示文章标题 作者 时间。高端大气&#xff5e; 增加页脚&#xff0c;显示 page/pageCount 加载 通过…

做策划有这些特质才能成为行业大咖,看看你符合几个

这个问题确实很重要&#xff0c;策划也不是职业也不是适合所有人的&#xff01; 首先&#xff0c;从性格方面来说吧。 有些人就是适合说话&#xff0c;有些人就是适合埋头苦干&#xff0c;还有一些人有强大的学习能力和逻辑思维。所以就是适合做创意类、创作类、策划类、统筹…

百度翻译API使用教程(前端+后端)

1.资格获取 首先我们需要登录百度翻译开放平台&#xff0c;获取开发者资格&#xff1a; 访问 百度翻译开放平台 然后进行注册&#xff08;如果有百度账号的话可以直接登录&#xff09; 注册成功后点击“产品服务”&#xff1a; 跳转到通用文本API界面&#xff1a; 在页面底…

怎么自学电脑编程

首要之首&#xff1a;不要急于选择一种语言 新手们有一个常见的错误就是犹豫于判断哪种编程语言是做好的、最该先学的。 我们有很多的选择&#xff0c;但你不能说那种语言最好。 我们应该理解&#xff1a;说到底&#xff0c;什么语言并不重要。 重要的是理解数据结构、控制逻辑…