ORACLE学习笔记(5)(伪列、日期函数、转换函数、数字函数、多值判断,exists)

Oracle中的伪列
SELECT * FROM EMP
在Oracle的表的使用过程中,实际表中还有一些附加的列,称为伪列。
伪列就像表中的列一样,但是在表中并不存储。伪列只能查询,不能进行增删改操作。
接下来学习两个伪列:ROWID 和 ROWNUM。

1.ROWID —(用来删除重复的数据)
表中的每一行在数据文件中都有一个物理地址,ROWID 伪列返回的就是该行的物理地址。
使用 ROWID 可以快速的定位表中的某一行。ROWID 值可以唯一的标识表中的一行。
由于 ROWID 返回的是该行的物理地址,因此使用 ROWID 可以显示行是如何存储的。

语法结构:删除重复数据,相同数据只保留一条
DELETE FROM 表名1 WHERE ROWID NOT IN (SELECT max(ROWID) FROM 表名1 GROUP BY 能区分唯一数据的字段);—如果不加GROUP BY 只保留表中一条数据
COMMIT;

CREATE TABLE EMP_1 AS SELECT * FROM EMP ;
---------------------------------------------
DELETE FROM EMP_1 A WHERE ROWID NOT IN(SELECT MIN(ROWID) FROM EMP_1 GROUP BY EMPNO);

------复制EMP表中的数据给 EMP_2 ,再删除EMP_2中重复的部门编号、

CREATE TABLE EMP_2 AS SELECT * FROM EMP WHERE 1=1;
SELECT * FROM EMP_2;

DELETE FROM EMP_2  WHERE ROWID NOT IN (SELECT MIN(ROWID) FROM EMP_2 A GROUP BY A.DEPTNO);
COMMIT;

2. ROWNUM —(只能用小于号或者小于等于号,不能用大于或者大于等于号,即:rownum < 或者 rownum <=)
在查询的结果集中,ROWNUM 为结果集中每一行标识一个行号,第一行返回1,第二行返回2,以此类推。
通过 ROWNUM 伪列可以限制查询结果集中返回的行数。

----查询出员工表中前5名员工的姓名,工作,工资。

SELECT
      A.ENAME
     ,A.JOB
     ,A.SAL 
FROM EMP A
WHERE ROWNUM <=5;
--------------------------------------------

ROWNUM 与 ROWID 不同,ROWID 是插入记录时生成,ROWNUM 是查询数据时生成。
ROWID 标识的是行的物理地址。ROWNUM 标识的是查询结果中的行的次序。

----------查询出员工表中工资前5名员工信息。

SELECT
      A1.*
FROM(SELECT
           A.ENAME
          ,A.SAL 
      FROM EMP A 
      ORDER BY A.SAL DESC
      )A1
WHERE ROWNUM <=5;      

----------查询出员工表中入职时间最早的5名员工信息。

SELECT
      A1.*
FROM (SELECT
         A.EMPNO,
         A.ENAME,
         A.JOB,
         A.MGR,
         A.HIREDATE,
         A.SAL,
         A.COMM,
         A.DEPTNO 
        FROM EMP A
        ORDER BY A.HIREDATE 
        )A1
WHERE ROWNUM<6  ;      

----------查询出员工表中工资大于平均工资前三名员工姓名、工资。

SELECT
      A1.ENAME
     ,A1.SAL 
FROM(SELECT
           B.EMPNO,
           B.ENAME,
           B.JOB,
           B.MGR,
           B.HIREDATE,
           B.SAL,
           B.COMM,
           B.DEPTNO
      FROM EMP B
      WHERE B.SAL>(SELECT
                         AVG(A.SAL)
                    FROM EMP A
                    )
      ORDER BY B.SAL DESC              
      )A1
WHERE ROWNUM<=3;      

Oracle单行函数

单行函数:对每一个函数应用在表的记录中时,只能输入一行结果,返回一个结果,
比如:MOD(x,y)返回x除以y的余数(x和y可以是两个整数,也可以是表中的整数列)。

常用的单行函数有:

  • 字符函数:对字符串操作。

  • 数字函数:对数字进行计算,返回一个数字。

  • 转换函数:可以将一种数据类型转换为另外一种数据类型。

  • 日期函数:对日期和时间进行处理。

  1. 字符函数

字符函数接受字符参数,这些参数可以是表中的列,也可以是一个字符串表达式。下表列出了常用的字符函数。

函数 说明

ASCII(x) 返回字符x的ASCII码。

-----查询EMP表中员工姓名的ASCII值
SELECT ASCII(A.ENAME) FROM EMP A;
-----查询'A'的ASCII值
SELECT ASCII('A') FROM DUAL;

CONCAT(x,y)                       连接字符串x和y。---之前学过'||',但是CONCAT只能两两拼接
-----拼接 '今晚','出去','浪!'-->‘今晚出去浪!’
SELECT
    CONCAT(CONCAT('今晚','出去'),'浪!')
FROM DUAL;
------------
SELECT '今晚'||'出去'||'浪!' FROM DUAL;

INSTR(x, str ,start ,n)       在x中查找str,可以指定从start开始,第n次出现。---找位置(常与SUBSTR连用)
---------在'ADFGHFGDSADSFDJGHFGD'中找出‘F’,从1开始 第3次出现的位置
SELECT INSTR('ADFGHFGDSADSFDJGHFGD','F',1,3) FROM DUAL;
---------在'ASDKJDFSALAKDJFKJDKDSH'中找出‘KD’,从倒数第1开始 第2次出现的位置
SELECT INSTR('ASDKJDFSALAKDJFKJDKDSH','KD',-1,2) from DUAL;
LENGTH(x)                         返回x的长度。
------查询你自己名字的长度
SELECT LENGTH('张浩宇') FROM DUAL;
LOWER(x)                          x转换为小写。
-----把'ADFghjdKH'转换成小写
SELECT LOWER('ADFghjdKH') FROM DUAL;

UPPER(x)                          x转换为大写。
-----把'ADFghjdKH'转换成大写
SELECT UPPER('ADFghjdKH') FROM DUAL;

LTRIM(x,trim_str)               把x的左边截去trim_str字符串,缺省截去空格。
----把'---阿斯蒂芬---'的左边截去'-'字符串
SELECT LTRIM('---阿斯蒂芬---','-') FROM DUAL;

RTRIM(x,trim_str)               把x的右边截去trim_str字符串,缺省截去空格。
----把'---阿斯蒂芬---'的右边截去'-'字符串
SELECT RTRIM('---阿斯蒂芬---','-') FROM DUAL;

TRIM(trim_str FROM x)           把x的两边截去trim_str字符串,缺省截去空格。
----把'---阿斯蒂芬---'的两边截去'-'字符串
SELECT TRIM('-'FROM '---阿斯蒂芬---') FROM DUAL;

REPLACE(x,old,new)                在x中查找old,并替换为new。
-----在'ASDLFKJFASD'中查找'ASD',并替换为'ABC'。
SELECT REPLACE('ASDLFKJFASD','ASD','ABC') FROM DUAL;

SUBSTR(x,start,length)          返回x的字串,从staart处开始,截取length个字符,缺省length,默认到结尾。
-----在'ASDLFKJKFCASDADF'中从第一位开始,截取'KFC'。
SELECT SUBSTR('ASDLFKJKFCASDADF',INSTR('ASDLFKJKFCASDADF','KFC',1,1),3) FROM DUAL;
SELECT REPLACE('ASDLFKJKFCASDADF','KFC','ABC') FROM DUAL;

示例 示例结果

SELECT ASCII('a') FROM DUAL 
SELECT CONCAT('Hello', ' world') FROM DUAL  
SELECT INSTR('Hello world''or') FROM DUAL  
SELECT LENGTH('Hello') FROM DUAL  
SELECT LOWER('hElLO') FROM DUAL;  
SELECT UPPER('hello') FROM DUAL 
SELECT LTRIM('===HELLO===', '=') FROM DUAL  
SELECT '=='||LTRIM('   HELLO===') FROM DUAL 
SELECT RTRIM('===HELLO===', '=') FROM DUAL  
SELECT '='||TRIM('   HELLO   ')||'=' FROM DUAL  
SELECT TRIM('=' FROM '===HELLO===') FROM DUAL 
SELECT REPLACE('ABCDE','CD','AAA') FROM DUAL  
SELECT SUBSTR('ABCDE',-2) FROM DUAL 
SELECT SUBSTR('ABCDE',2,3) FROM DUAL  

DUAL介绍

dual是一张虚拟表,只有一行一列,用来构成 select 的语法规则。
Oracle的查询中,必须使用“select 列… from 表”的完整语法,当查询单行函数的时候,from 后面使用 DUAL 表
,dual 表在系统中只有一行一列,该表在输出单行函数时为了 select…from 的语法完整性而使用。

—查询员工姓名以’S’结尾的员工信息

SELECT
     A.EMPNO,
     A.ENAME,
     A.JOB,
     A.MGR,
     A.HIREDATE,
     A.SAL,
     A.COMM,
     A.DEPTNO
FROM EMP A
where substr(a.ename,-1,1)='S';
-------------------------------------------
  1. *数字函数
    ----有小数点的时候,小数点的右边代表正数,左边代表负数
    数字函数接受数字参数,参数可以来自表中的一列,也可以是一个数字表达式。
函数  说明  示例
ABS(x)  x绝对值  ABS(-3)=3
MOD(x,y)  x除以y的余数 MOD(8,3)=2
POWER(x,y)  x的y次幂 POWER(2,3)=8
ROUND(x,y)  x在第y位四舍五入 ROUND(3.456,2)=3.46
TRUNC(x,y)  x在第y位截断 TRUNC(3.456,2)=3.45

表3 数字函数
说明:

  1. ROUND(X[,Y]),四舍五入。

在缺省y时,默认y=0;比如:ROUND(3.56)=4。
SELECT ROUND(5.654,1) FROM DUAL;
SELECT TRUNC(3.1635,1) FROM DUAL;

y是正整数,就是四舍五入到小数点后y位。ROUND(5.654,2)=5.65。
SELECT ROUND(2435.654,-2) FROM DUAL;

y是负整数,四舍五入到小数点左边|y|位。ROUND(351.654,-2)=400。

  1. TRUNC(x[,y]),直接截取,不四舍五入。

在缺省y时,默认y=0;比如:TRUNC (3.56)=3。
y是正整数,就是四舍五入到小数点后y位。TRUNC (5.654,2)=5.65。
y是负整数,四舍五入到小数点左边|y|位。TRUNC (351.654,-2)=300。

  1. 日期函数

日期函数对日期进行运算。常用的日期函数有:

1.ADD_MONTHS(d,n),在某一个日期d上,加上指定的月数n,返回计算后的新日期。d表示日期,n表示要加的月数。

—当前日期两个月后的日期
SELECT ADD_MONTHS(SYSDATE,-2) FROM DUAL;

2.LAST_DAY(d),返回指定日期当月的最后一天。
—查询当前时间的最后一天
select LAST_DAY(SYSDATE) FROM DUAL;
----查询你出生日期的最后一天

SELECT LAST_DAY(TO_DATE('20200105','YYYYMMDD'))FROM DUAL;

----查询你的生日是星期谁?

SELECT to_char(TO_DATE('20200105','YYYYMMDD'),'DAY')FROM DUAL;

----查询当前时间是第几季度

SELECT TO_CHAR(SYSDATE,'mm') FROM DUAL;

3.ROUND(d,fmt),返回一个以fmt为格式的四舍五入日期值,d是日期,fmt是格式模型。默认fmt为DDD,即月中的某一天。

  • 如果fmt为“YEAR”则舍入到某年的1月1日,即前半年舍去,后半年作为下一年。

  • 如果fmt为“MONTH”则舍入到某月的1日,即前月舍去,后半月作为下一月。

  • 默认为“DDD”,即月中的某一天,最靠近的天,前半天舍去,后半天作为第二天。

  • 如果fmt为“DAY”则舍入到最近的周的周日,即上半周舍去,下半周作为下一周周日。

SELECT ROUND(SYSDATE,'DAY') FROM DUAL;
SELECT ROUND(TO_DATE('20210706','YYYYMMDD'),'MM')FROM DUAL;

与 ROUND 对应的函数时 TRUNC(d[,fmt])对日期的操作
,TRUNC 与 ROUND 非常相似,只是不对日期进行舍入,直接截取到对应格式的第一天。
TRUNC(date[,fmt]):将date截取到fmt指定的形式,如果fmt省略,则截取到最近的日期。

------求你出生日期是星期几

---'19990701'
SELECT
      TO_CHAR(TO_DATE('19990701','YYYYMMDD'),'DAY')
FROM DUAL;

------求你出生那年有多少天
—1、先截取到年初
—2、年初加12月
—3、两个年份相减

SELECT
     TRUNC(TO_DATE('19990701','YYYYMMDD'),'YYYY')--年初
    ,ADD_MONTHS(TRUNC(TO_DATE('19990701','YYYYMMDD'),'YYYY'),12)--下年年初
    ,ADD_MONTHS(TRUNC(TO_DATE('19990701','YYYYMMDD'),'YYYY'),12)- TRUNC(TO_DATE('19990701','YYYYMMDD'),'YYYY')
FROM DUAL;

------求你出生日期月末是几号

SELECT
      TO_CHAR(TO_DATE('19990701','YYYYMMDD'),'DAY')---出生日期
     ,LAST_DAY(TO_DATE('19990701','YYYYMMDD')) 
FROM DUAL;

------求你出生日期离年初过了多少天

SELECT
     TRUNC(TO_DATE('19990701','YYYYMMDD'),'YYYY')--年初
    ,TO_DATE('19990701','YYYYMMDD')--出生日期
    ,TO_DATE('19990701','YYYYMMDD')-TRUNC(TO_DATE('19990701','YYYYMMDD'),'YYYY')
FROM DUAL;

------求你出生日期离年末还有多少天

SELECT
     TO_DATE('19990701','YYYYMMDD')--出生日期
    ,LAST_DAY(TO_DATE('19990701','YYYYMMDD'))--出生日期 最后一天
    ,ADD_MONTHS(LAST_DAY(TO_DATE('19990701','YYYYMMDD')),5)---年末
    ,ADD_MONTHS(LAST_DAY(TO_DATE('19990701','YYYYMMDD')),5)-TO_DATE('19990701','YYYYMMDD')
FROM DUAL;


  1. 转换函数

转换函数将值从一种数据类型转换为另外一种数据类型。

常用的转换函数有:

–1.TO_CHAR(d,fmt)

把日期和数字转换为指定格式的字符串。fmt是格式化字符串,日期的格式化字符串前面已经学习过。

SELECT 
     TO_CHAR(SYSDATE,'YYYYMMDD')
FROM DUAL;

代码演示:TO_CHAR对日期的处理

SELECT TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS') FROM DUAL
SELECT 1234 FROM DUAL;

代码演示:TO_CHAR对数字的处理

SELECT TO_CHAR(123456) FROM DUAL

2.TO_DATE(x ,fmt)

把一个字符串以fmt格式转换为一个日期类型。

代码演示:TO_DATE函数

SELECT TO_DATE('20170703145533','YYYYMMDD HH24:MI:SS') FROM DUAL

3.TO_NUMBER(x[,fmt])----只能是纯阿拉伯数字才能转换(要想把时间类型的数据转换成数字类型,一定要先TO_CHAR成纯阿拉伯数字的字符串)

把一个字符串以fmt格式转换为一个数字。

-----把系统时间转换成数字类型

SELECT
     TO_NUMBER(TO_CHAR(SYSDATE,'YYYYMMDD'))
FROM DUAL;

代码演示:TO_NUMBER函数
SELECT TO_NUMBER(‘123456’) FROM DUAL

5.其他常用函数

NVL(列,默认值) 如果列值为null,则使用默认值表示—指定的默认值一定要跟列的数据类型一致

SELECT
      NVL(A.COMM,10000)
FROM EMP A;

NVL2(列,返回值1,返回值2) 如果列值不为null,返回结果1;如果列值为null,返回结果2 —指定的值一定要跟列的数据类型一致

SELECT
     NVL2(A.COMM,2000,0)
FROM EMP A;

DECODE(列|值,判断值1,返回值1,判断值2,返回值2,…,默认值)–判断值1:表中具体的数据 ,返回值1:你指定的值
–不是所有数据库都可用 多值判断,如果列值与判断值相同,则显示对应返回值输出,如果没有满足条件,则显示默认值

CLERK    --- 办事员
SALESMAN  --销售员
PRESIDENT --主席
MANAGER   --- 经理
ANALYST   --- 分析师

SELECT
   DECODE(A.JOB,'CLERK','办事员','SALESMAN','销售员','PRESIDENT','主席','MANAGER','经理','ANALYST','分析师','鬼')
FROM EMP A;

–CASE WHEN 的语法结构:
CASE WHEN 条件1 THEN 返回值1
WHEN 条件2 THEN 返回值2
… ELSE 默认值
END --条件1:列名=具体的数据,返回值1:你指定的值
–所有数据库都支持 用于实现多条件判断,如果都不满足条件,则返回默认值

SELECT
     A.ENAME
    ,CASE WHEN A.JOB='CLERK' THEN '办事员'
           WHEN A.JOB='SALESMAN' THEN '销售员'
            WHEN A.JOB='PRESIDENT' THEN '主席'
              WHEN A.JOB='MANAGER' THEN '经理'
                WHEN A.JOB='ANALYST' THEN '分析师'
                  ELSE ''
                  END JOB
     ,A.HIREDATE
     ,A.SAL             
FROM EMP A 
  1. NVL(x,value)
    如果x为空,返回 value,否则返回 x。

—对工资是2000元以下的员工,如果没有发奖金,每人奖金100元。

----列出EMP员工的姓名,工资,以及工资评价 --(按工资等级来分,大于3000工资很高,大于2000,工资一般,小于1000,混子)

SELECT
     A.ENAME 姓名
    ,A.SAL  工资
    ,CASE WHEN A.SAL>3000 THEN '工资很高' 
          WHEN A.SAL>=1000 THEN '工资一般'
          WHEN A.SAL<1000 THEN '混子'
            END 工资评价
FROM EMP A;

----EXISTS(子查询) 用于判断子查询是否有数据返回,如果有则成立,否则不成立。
–列出有员工的部门信息

SELECT
      A.DEPTNO,
      A.DNAME,
      A.LOC
FROM DEPT A
WHERE EXISTS (SELECT B.DEPTNO FROM EMP B WHERE B.DEPTNO=A.DEPTNO);
----------------------------------------
SELECT
      A.DEPTNO,
      A.DNAME,
      A.LOC
FROM DEPT A
WHERE A.DEPTNO IN(SELECT B.DEPTNO FROM EMP B);

—查询EMP表中 和10号部门的工作岗位相同,且工资大于1000的员工姓名、工作、薪资–用两种方法来做

SELECT
      B.ENAME
     ,B.JOB
     ,B.SAL 
     ,B.DEPTNO
FROM EMP B
WHERE B.JOB IN(SELECT
                      A.JOB
                FROM EMP A
                WHERE A.DEPTNO=10
                )
      AND B.SAL>1000
      AND B.DEPTNO<>10;

------------------------------
SELECT
      B.ENAME
     ,B.JOB
     ,B.SAL 
     ,B.DEPTNO
FROM EMP B
WHERE EXISTS(SELECT
                  A.JOB
             FROM EMP A
             WHERE A.DEPTNO=10
                 AND A.JOB=B.JOB
                )
      AND B.SAL>1000
      AND B.DEPTNO<>10;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值