(十)单行函数

单行函数: 只对一行数据进行变换,产生一个结果,可以没有参数,但必须有返回值,如concat,nvl

1.字符函数

2.数值函数

3.时间函数

4.日期函数

5.转换函数

6.通用函数

7.条件表达式

 

1.字符函数

操作对象是字符串,大致可分为两类:

一类是大小写控制函数,主要有upper,lower,initcap

SQL> select lower(ename) from emp where comm is not null;

LOWER(ENAM
----------
allen
ward
martin
turner

已用时间:  00: 00: 00.06
SQL>
SQL> select lower('HELLO') 转小写,upper('hello') 转大写,initcap('hello world') 首字母大写 from dual;

转小  转大  首字母大写
----- ----- -----------
hello HELLO Hello World

已用时间:  00: 00: 00.02
SQL>

另一类是字符控制函数

有:CONCAT,SUBSTR , LENGTH / LENGTHB , INSTR , LPAD, RPAD, TRIM , REPLACE

SUBSTR :

substr(a,b):从a中,第b位开始取(计数从 1 开始),取到结尾

SQL> select substr('hello world',3) from dual;

SUBSTR('H
---------
llo world

已用时间:  00: 00: 00.02
substr(a,b,c):从a中,第b位开始取(计数从 1 开始),向右取 c 位

SQL> ed
已写入 file afiedt.buf

  1* select substr('hello world',3,5) from dual
SQL> /

SUBST
-----
llo w

已用时间:  00: 00: 00.02

 

LENGTH 字符数/,LENGTHB 字节数

SQL> select length('hello world') from dual;

LENGTH('HELLOWORLD')
--------------------
                  11

已用时间:  00: 00: 00.02
SQL> select length('中国') from dual;

LENGTH('中国')
--------------
             2

已用时间:  00: 00: 00.01
SQL> select lengthb('中国') from dual;

LENGTHB('中国')
---------------
              4

已用时间:  00: 00: 00.01
SQL> select lengthb('hello world') from dual;

LENGTHB('HELLOWORLD')
---------------------
                   11

已用时间:  00: 00: 00.02

 

instr 在母串中查找子串,找到返回下表,计数从 1 开始,没有返回 0 ;

  1* select instr('hello world','llo') from dual
SQL> /

INSTR('HELLOWORLD','LLO')
-------------------------
                        3

已用时间:  00: 00: 00.02
SQL>

 

lpad 左填充,参数1:待填充的字符串,参数2:填充后字符串的总长度(字节),参数3:填充什么

SQL> select lpad('abcd',10,'*') '',rpad('abcd',10,'#') 右 from dual;
select lpad('abcd',10,'*') '',rpad('abcd',10,'#') 右 from dual
                           *1 行出现错误:
ORA-00923: 未找到要求的 FROM 关键字


已用时间:  00: 00: 00.04
SQL> c /''/"左"
  1* select lpad('abcd',10,'*') "左",rpad('abcd',10,'#') 右 from dual
SQL> /

左         右
---------- ----------
******abcd abcd######

已用时间:  00: 00: 00.04
SQL>

 

trim 去掉前后指定的字符

SQL> select trim('H' from 'HelloH' ) from dual;

TRIM
----
ello

已用时间:  00: 00: 00.02
SQL> select ename from emp;

ENAME
----------
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
JAMES
FORD
MILLER

已选择14行。

已用时间:  00: 00: 00.07
SQL> select trim('S' from ename) from emp;

TRIM('S'FR
----------
MITH
ALLEN
WARD
JONE
MARTIN
BLAKE
CLARK
COTT
KING
TURNER
ADAM
JAME
FORD
MILLER

已选择14行。

已用时间:  00: 00: 00.04
SQL>

 

replace 替换

已用时间:  00: 00: 00.04
SQL> select replace('hello','l','*') from dual;

REPLA
-----
he**o

已用时间:  00: 00: 00.02
SQL> select replace('hello','l','') from dual;

REP
---
heo

已用时间:  00: 00: 00.02
SQL>

 

2.数值函数

ROUND:四舍五入

  ROUND(45.926, 2)  45.93   

TRUNC:截断

  ROUND(45.926, 2)  45.92

MOD:求余

  MOD(1600, 300)

round(45.926, 2) , 2 表达的是保留两位小数,第二个参数如果是 0 ,可以不写,正负表示小数点之后或之前的位数

SQL> select round(45.926,2) 一,round(45.926,1) 二,round(45.926,0) 三,round(45.926,-1) 四,round(45.926,-2) 五 from dual;

        一         二         三         四         五
---------- ---------- ---------- ---------- ----------
     45.93       45.9         46         50          0

已用时间:  00: 00: 00.08
SQL>
SQL> ed
已写入 file afiedt.buf

  1* select TRUNC(45.926,2) 一,TRUNC(45.926,1) 二,TRUNC(45.926,0) 三,TRUNC(45.926,-1) 四,TRUNC(45.926,-2) 五 from dual
SQL> /

        一         二         三         四         五
---------- ---------- ---------- ---------- ----------
     45.92       45.9         45         40          0

已用时间:  00: 00: 00.02
SQL>

 

SQL> select mod(100,3) from dual;

MOD(100,3)
----------
         1

已用时间:  00: 00: 00.02
SQL>

 

3.时间函数

SQL> select sysdate from dual;

SYSDATE
--------------
15-4月 -19

已用时间:  00: 00: 00.03
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;

TO_CHAR(SYSDATE,'YY
-------------------
2019-04-15 15:12:20

已用时间:  00: 00: 00.02
SQL> select to_char(sysdate,'day') from dual;

TO_CHAR(S
---------
星期一

已用时间:  00: 00: 00.02
SQL>

日期加减数字,结果仍为日期。单位:天

SQL> select (sysdate-1) 昨天,(sysdate) 今天,(sysdate+1) 明天 from dual;

昨天           今天           明天
-------------- -------------- --------------
14-4月 -19     15-4月 -19     16-4月 -19

已用时间:  00: 00: 00.02
SQL> ed
已写入 file afiedt.buf

  1* select to_char(sysdate-1,'yyyy-mm-dd') 昨天,to_char(sysdate,'yyyy-mm-dd') 今天,to_char(sysdate+1,'yyyy-mm-dd') 明天 from dual
SQL> /

昨天       今天       明天
---------- ---------- ----------
2019-04-14 2019-04-15 2019-04-16

已用时间:  00: 00: 00.02
SQL>

计算工龄

  1* select ename,hiredate,(sysdate-hiredate) 天,(sysdate-hiredate)/7 星期,(sysdate-hiredate)/30 月,(sysdate-hiredate)/365from emp
SQL> /

ENAME      HIREDATE               天       星期         月         年
---------- -------------- ---------- ---------- ---------- ----------
SMITH      17-12月-80     13998.6403 1999.80575 466.621342 38.3524391
ALLEN      20-2月 -81     13933.6403 1990.52004 464.454676 38.1743569
WARD       22-2月 -81     13931.6403 1990.23432 464.388009 38.1688774
JONES      02-4月 -81     13892.6403  1984.6629 463.088009 38.0620281
MARTIN     28-9月 -81     13713.6403 1959.09147 457.121342 37.5716172
BLAKE      01-5月 -81     13863.6403 1980.52004 462.121342 37.9825761
CLARK      09-6月 -81     13824.6403 1974.94861 460.821342 37.8757268
SCOTT      19-4月 -87     11684.6403 1669.23432 389.488009 32.0127131
KING       17-11月-81     13663.6403 1951.94861 455.454676 37.4346309
TURNER     08-9月 -81     13733.6403 1961.94861 457.788009 37.6264117
ADAMS      23-5月 -87     11650.6403 1664.37718 388.354676 31.9195624
JAMES      03-12月-81     13647.6403  1949.6629 454.921342 37.3907952
FORD       03-12月-81     13647.6403  1949.6629 454.921342 37.3907952
MILLER     23-1月 -82     13596.6403 1942.37718 453.221342 37.2510692

已选择14行。

已用时间:  00: 00: 00.06
SQL>

注意:日期和日期可以相减,但是不允许相加。日期只能和数字相加!

 

4.日期函数

上述求取员工工龄的结果计算不准确,如果想其算准确,可以使用日期函数来做。

months_between:两个日期值相差的月数(精确值)

SQL> ed
已写入 file afiedt.buf

  1* select (sysdate-hiredate)/30 一,months_between(sysdate,hiredate) 二 from emp
SQL> /

        一         二
---------- ----------
466.621542 459.956331
464.454876 457.859557
464.388209 457.795041
463.088209 456.440202
457.121542 450.601493
462.121542  455.47246
460.821542 454.214396
389.488209 383.891815
455.454876 448.956331
457.788209 451.246654
388.354876 382.762783
454.921542 448.407944
454.921542 448.407944
453.221542 446.762783

已选择14行。

已用时间:  00: 00: 00.06
SQL>

 

add_months:在某日期值上加上多少的月,整数向后计算,负数向前计算

计算95个月之后是哪年,哪月,哪天

SQL> select add_months(sysdate,95) 哪一天 from dual;

哪一天
--------------
15-3月 -27

已用时间:  00: 00: 00.01
SQL>

last_day,日期所在月的最后一天

SQL> select last_day(sysdate) from dual;

LAST_DAY(SYSDA
--------------
30-4月 -19

已用时间:  00: 00: 00.02
SQL>

next_day,指定日期的下一个日期

SQL> select next_day(sysdate,'星期一') from dual;

NEXT_DAY(SYSDA
--------------
22-4月 -19

已用时间:  00: 00: 00.02
SQL> select next_day(sysdate,'星期二') from dual;

NEXT_DAY(SYSDA
--------------
16-4月 -19

已用时间:  00: 00: 00.02
SQL>

round,trunc 对日期型数据进行四舍五入和截断

SQL> select round(sysdate,'month') from dual;

ROUND(SYSDATE,
--------------
01-4月 -19

已用时间:  00: 00: 00.02
SQL> ed
已写入 file afiedt.buf

  1* select round(sysdate,'month'),round(sysdate,'year') from dual
SQL> /

ROUND(SYSDATE, ROUND(SYSDATE,
-------------- --------------
01-4月 -19     01-1月 -19

已用时间:  00: 00: 00.02
SQL> ed
已写入 file afiedt.buf

  1* select trunc(sysdate,'month'),trunc(sysdate,'year') from dual
SQL> /

TRUNC(SYSDATE, TRUNC(SYSDATE,
-------------- --------------
01-4月 -19     01-1月 -19

已用时间:  00: 00: 00.01
SQL> ed
已写入 file afiedt.buf

  1* select round('17-4月-19','month'),round('17-10月-19','year') from dual
SQL> /
select round('17-4月-19','month'),round('17-10月-19','year') from dual
             *1 行出现错误:
ORA-01722: 无效数字


已用时间:  00: 00: 00.03
SQL> ed
已写入 file afiedt.buf

  1* select round(to_date('17-4月-19'),'month'),round(to_date('17-10月-19'),'year') from dual
SQL> /

ROUND(TO_DATE( ROUND(TO_DATE(
-------------- --------------
01-5月 -19     01-1月 -20

已用时间:  00: 00: 00.01

 

5.转换函数

显示类型转换

to_char, to_date,to_number

隐式类型转换

SQL> select * from emp where hiredate = '02-4月-81';

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7566 JONES      MANAGER         7839 02-4月 -81           2975                    20

已用时间:  00: 00: 00.02
SQL>

 

SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss "今天是" day') from dual;

TO_CHAR(SYSDATE,'YYYY-MM-DDHH24:MI:S
------------------------------------
2019-04-15 16:01:56 今天是 星期一

已用时间:  00: 00: 00.02
SQL>

反向操作

SQL> ed
已写入 file afiedt.buf

  1* select to_date('2019-04-15 16:01:56 今天是 星期一','yyyy-mm-dd hh24:mi:ss "今天是" day') from dual
SQL> /

TO_DATE('2019-
--------------
15-4月 -19

已用时间:  00: 00: 00.02
SQL>

 

查询员工薪水:2 位小数,本地货币代码,千位符

SQL> select to_char(sal,'L9,999.99') from emp;

TO_CHAR(SAL,'L9,999
-------------------
           ¥800.00
         ¥1,600.00
         ¥1,250.00
         ¥2,975.00
         ¥1,250.00
         ¥2,850.00
         ¥2,450.00
         ¥3,000.00
         ¥5,000.00
         ¥1,500.00
         ¥1,100.00
           ¥950.00
         ¥3,000.00
         ¥1,300.00

已选择14行。

已用时间:  00: 00: 00.08
SQL>

 

SQL> select to_number('¥1,666.00','L9,999.99') 转换数字 from dual;

  转换数字
----------
      1666

已用时间:  00: 00: 00.02
SQL>

 

6.通用函数 

NVL(expr1, expr2)

NVL2(expr1, expr2, expr3)

NULLIF(expr1, expr2)

COALESCE(expr1, expr2, ..., exprn)

nvl2 是 nvl  的增强版 nvl2(a, b, c),若 a = null, 则返回 c, 否则返回 b

用nvl2 求员工的年收入

SQL> select ename,sal*12 + nvl2(comm,comm,0) from emp;

ENAME      SAL*12+NVL2(COMM,COMM,0)
---------- ------------------------
SMITH                          9600
ALLEN                         19500
WARD                          15500
JONES                         35700
MARTIN                        16400
BLAKE                         34200
CLARK                         29400
SCOTT                         36000
KING                          60000
TURNER                        18000
ADAMS                         13200

ENAME      SAL*12+NVL2(COMM,COMM,0)
---------- ------------------------
JAMES                         11400
FORD                          36000
MILLER                        15600

已选择14行。

 

nullif(a, b), 当a = b 时返回 null, 不相等时返回 a 的值

SQL> select nullif('L9,999.99','L9,999.99') from dual;

NULLIF('L
---------


SQL> select nullif('L9,999.99','L9,999.9') from dual;

NULLIF('L
---------
L9,999.99

SQL>

 

coalesce(a, b, c, d,..., n),从左往右找参数中第一个不为 空的值

SQL> select comm,sal,coalesce(comm,sal) from emp;

      COMM        SAL COALESCE(COMM,SAL)
---------- ---------- ------------------
                  800                800
       300       1600                300
       500       1250                500
                 2975               2975
      1400       1250               1400
                 2850               2850
                 2450               2450
                 3000               3000
                 5000               5000
         0       1500                  0
                 1100               1100
                  950                950
                 3000               3000
                 1300               1300

已选择14行。

SQL>

 

7.条件表达式

老板打算给员工涨工资:总裁涨1000,经理涨800,其他人涨400,将涨前,涨后的薪水列出。

SQL中 没有if else 语句,可以使用case,或者decode

case,  是一个表达式,其语法为:

CASE expr WHEN comparison_expr1 THEN return_expr1
    [WHEN comparison_expr2 THEN return_expr2
    WHEN comparison_exprn THEN return_exprn
    ELSE else_expr]
END
已写入 file afiedt.buf

  1  select ename,job,sal 涨薪水前, case job when 'PRESIDENT' then sal + 1000
  2  when 'MANAGER' then sal + 800
  3  else sal + 400
  4* end 涨薪水后 from emp
SQL> /

ENAME      JOB         涨薪水前   涨薪水后
---------- --------- ---------- ----------
SMITH      CLERK            800       1200
ALLEN      SALESMAN        1600       2000
WARD       SALESMAN        1250       1650
JONES      MANAGER         2975       3775
MARTIN     SALESMAN        1250       1650
BLAKE      MANAGER         2850       3650
CLARK      MANAGER         2450       3250
SCOTT      ANALYST         3000       3400
KING       PRESIDENT       5000       6000
TURNER     SALESMAN        1500       1900
ADAMS      CLERK           1100       1500
JAMES      CLERK            950       1350
FORD       ANALYST         3000       3400
MILLER     CLERK           1300       1700

已选择14行。

SQL>

decode

DECODE(col | expression, search1 ,result1
[search2 ,result2,...]
[,default])
除第一个和最后一个参数之外,中间参数都是成对出现的(参1,条件,值,条件,值,...,条件,值,尾参)

 

SQL> ed
已写入 file afiedt.buf

  1  select ename,job,sal 涨薪水前, decode(job, 'PRESIDENT' ,sal + 1000,
  2   'MANAGER' ,sal + 800
  3  ,sal + 400)
  4* as 涨薪水后 from emp
SQL> /

ENAME      JOB         涨薪水前   涨薪水后
---------- --------- ---------- ----------
SMITH      CLERK            800       1200
ALLEN      SALESMAN        1600       2000
WARD       SALESMAN        1250       1650
JONES      MANAGER         2975       3775
MARTIN     SALESMAN        1250       1650
BLAKE      MANAGER         2850       3650
CLARK      MANAGER         2450       3250
SCOTT      ANALYST         3000       3400
KING       PRESIDENT       5000       6000
TURNER     SALESMAN        1500       1900
ADAMS      CLERK           1100       1500
JAMES      CLERK            950       1350
FORD       ANALYST         3000       3400
MILLER     CLERK           1300       1700

已选择14行。

SQL>

 

posted @ 2019-04-15 16:50  狂奔~  阅读(380)  评论(0编辑  收藏  举报