1.作用
2.类型
单行函数用于描述SQL中不同类型的函数,在SELECT语句中使用字符,数字和日期函数。
1.作用
单行函数用于操作数据项。它们接受一个或多个参数,并为查询返回的每一行返回一个值,可以是:用户提供的值、变量值、列名或表达式。
2.特点
4.dual表
DUAL表是一个“伪表”(虚拟表),只包含一个列DUMMY,数据类型为VARCHAR2(1)。表只包含一行,其DUMMY列的值为X。
DUAL表是为了语法上的完整性。
可以用来当计算器、返回日期等测试函数和表达式
SQL> select * from dual;
D
-
X
SQL> select 123*4 from dual;
123*4
----------
492
SQL> select sysdate from dual;
SYSDATE
---------
14-MAY-19
大小写转换函数 | 字符处理函数 |
---|---|
LOWER、UPPER、INITCAP | CONCAT、SUBSTR、LENGTH、INSTR、LPAD/RPAD、TRIM、REPLACE |
链接字符串、列、表达式
SQL> select concat('good','dba') from dual;
CONCAT(
-------
gooddba
SQL> select ename||' is a '||job from emp;
ENAME||'ISA'||JOB
-------------------------
SMITH is a CLERK
ALLEN is a SALESMAN
WARD is a SALESMAN
JONES is a MANAGER
MARTIN is a SALESMAN
BLAKE is a MANAGER
CLARK is a MANAGER
SCOTT is a ANALYST
KING is a PRESIDENT
TURNER is a SALESMAN
ADAMS is a CLERK
JAMES is a CLERK
FORD is a ANALYST
MILLER is a CLERK
14 rows selected.
SQL> select concat(concat(ename,' is '),job) a
2 from emp;
A
-----------------------
SMITH is CLERK
ALLEN is SALESMAN
WARD is SALESMAN
JONES is MANAGER
MARTIN is SALESMAN
BLAKE is MANAGER
CLARK is MANAGER
SCOTT is ANALYST
KING is PRESIDENT
TURNER is SALESMAN
ADAMS is CLERK
JAMES is CLERK
FORD is ANALYST
MILLER is CLERK
14 rows selected.
截取字符串
SQL> select substr('oracle',1,3) from dual;
SUB
---
ora
SQL> select substr('oracle',-2,2) from dual;
SU
--
le
SQL> select substr('oracle',4) from dual;
SUB
---
cle
SQL> select substr('oracle',-5) from dual;
SUBST
-----
racle
获取字符数
SQL> select length('oracle') from dual;
LENGTH('ORACLE')
----------------
6
SQL> select instr('oracle','cle') from dual;
INSTR('ORACLE','CLE')
---------------------
4
instr经常用来做判断,判断一个字符串是否在另外一个字符串中
SQL> select ename,instr(ename,'A') from emp;
ENAME INSTR(ENAME,'A')
---------- ----------------
SMITH 0
ALLEN 1
WARD 2
JONES 0
MARTIN 2
BLAKE 3
CLARK 3
SCOTT 0
KING 0
TURNER 0
ADAMS 1
JAMES 2
FORD 0
MILLER 0
14 rows selected.
SQL> select instr('1*2*3*4*5*','*',3,4) from dual;
INSTR('1*2*3*4*5*','*',3,4)
---------------------------
10
SQL> select instr('1*2*3*4*5*','*',-3,2) from dual;
INSTR('1*2*3*4*5*','*',-3,2)
----------------------------
6
SQL> select ename,sal,rpad(sal,5,'*') from emp;
ENAME SAL RPAD(SAL,5,'*')
---------- ---------- --------------------
SMITH 800 800**
ALLEN 1600 1600*
WARD 1250 1250*
JONES 2975 2975*
MARTIN 1250 1250*
BLAKE 2850 2850*
CLARK 2450 2450*
SCOTT 3000 3000*
KING 5000 5000*
TURNER 1500 1500*
ADAMS 1100 1100*
JAMES 950 950**
FORD 3000 3000*
MILLER 1300 1300*
14 rows selected.
SQL> select sal,lpad(sal,4,0),rpad(sal,4,0) from emp;
SAL LPAD(SAL,4,0) RPAD(SAL,4,0)
---------- ---------------- ----------------
800 0800 8000
1600 1600 1600
1250 1250 1250
2975 2975 2975
1250 1250 1250
2850 2850 2850
2450 2450 2450
3000 3000 3000
5000 5000 5000
1500 1500 1500
1100 1100 1100
950 0950 9500
3000 3000 3000
1300 1300 1300
14 rows selected.
去掉前后空格,或者从后面串首尾去掉前面字符:
SQL> select trim(' hello ') from dual;
TRIM(
-----
hello
SQL> select length(' hello '),length(trim(' hello ')) from dual;
LENGTH('HELLO') LENGTH(TRIM('HELLO'))
--------------- ---------------------
7 5
四舍五入到指定的十进制值
SQL> select round(45.368,0) from dual;
ROUND(45.368,0)
---------------
45
SQL> select round(45.237,-1) from dual;
ROUND(45.237,-1)
----------------
50
SQL> select round(45.932,2) from dual;
ROUND(45.932,2)
---------------
45.93
SQL> select round(45.677,2) from dual;
ROUND(45.677,2)
---------------
45.68
截断到指定十进制值
SQL> select trunc(45.675,2) from dual;
TRUNC(45.675,2)
---------------
45.67
SQL> select trunc(45.677,2) from dual;
TRUNC(45.677,2)
---------------
45.67
返回余数
SQL> select mod(1600,300) from dual;
MOD(1600,300)
-------------
100
Oracle内部使用数字存储日期:世纪、年、月、日、小时
默认日期格式:DD-MON-RR
SYSDATE是一个日期函数,返回当前数据库服务器的日期和时间。可以像使用任何其他列名一样使用SYSDATE。
SQL> select sysdate from dual;
SYSDATE
---------
14-MAY-19
修改当前session日期格式
SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss day';
Session altered.
SQL> select sysdate from dual;
SYSDATE
-----------------------------
2019-05-14 15:10:57 tuesday
SQL> select hiredate from emp;
HIREDATE
-----------------------------
1980-12-17 00:00:00 wednesday
1981-02-20 00:00:00 friday
1981-02-22 00:00:00 sunday
1981-04-02 00:00:00 thursday
1981-09-28 00:00:00 monday
1981-05-01 00:00:00 friday
1981-06-09 00:00:00 tuesday
1987-04-19 00:00:00 sunday
1981-11-17 00:00:00 tuesday
1981-09-08 00:00:00 tuesday
1987-05-23 00:00:00 saturday
1981-12-03 00:00:00 thursday
1981-12-03 00:00:00 thursday
1982-01-23 00:00:00 saturday
14 rows selected.
计算方法 | 计算公式 |
---|---|
date+number | 加几天(结果还是日期) |
date-number | 减几天 |
date-date | 两个日期相减返回日期之间的相差天数 |
date+number/24 | 加小时到日期上 |
因为数据库将日期存储为数字,所以可以使用加减法等算术运算符执行计算。
SQL> alter session set nls_date_format = 'DD-MON-RR';
Session altered.
SQL> select sysdate from dual;
SYSDATE
---------
14-MAY-19
SQL> select sysdate + 1 from dual;
SYSDATE+1
---------
15-MAY-19
SQL> select ename,hiredate,round((sysdate-hiredate)/365,0) years from emp;
ENAME HIREDATE YEARS
---------- --------- ----------
SMITH 17-DEC-80 38
ALLEN 20-FEB-81 38
WARD 22-FEB-81 38
JONES 02-APR-81 38
MARTIN 28-SEP-81 38
BLAKE 01-MAY-81 38
CLARK 09-JUN-81 38
SCOTT 19-APR-87 32
KING 17-NOV-81 38
TURNER 08-SEP-81 38
ADAMS 23-MAY-87 32
JAMES 03-DEC-81 37
FORD 03-DEC-81 37
MILLER 23-JAN-82 37
14 rows selected.
SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss day';
Session altered.
SQL> select sysdate +1/24 from dual;
SYSDATE+1/24
-----------------------------
2019-05-14 16:18:34 tuesday
SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss day';
Session altered.
SQL> select sysdate +1/24 from dual;
SYSDATE+1/24
-----------------------------
2019-05-14 16:18:34 tuesday
两个日期相差的月数
SQL> select empno,ename,months_between(sysdate,hiredate) months from emp;
EMPNO ENAME MONTHS
---------- ---------- ----------
7369 SMITH 460.923843
7499 ALLEN 458.827069
7521 WARD 458.762553
7566 JONES 457.407714
7654 MARTIN 451.569004
7698 BLAKE 456.439972
7782 CLARK 455.181907
7788 SCOTT 384.859327
7839 KING 449.923843
7844 TURNER 452.214166
7876 ADAMS 383.730295
7900 JAMES 449.375456
7902 FORD 449.375456
7934 MILLER 447.730295
14 rows selected.
向指定日期中加上若干月数
SQL> select sysdate,add_months(sysdate,-12) from dual;
SYSDATE ADD_MONTHS(SYSDATE,-12)
----------------------------- -----------------------------
2019-05-14 15:20:53 tuesday 2018-05-14 15:20:53 monday
只有增加月的函数,没有增加年和日的函数
显示本月的最后一天
SQL> select sysdate,last_day(sysdate) from dual;
SYSDATE LAST_DAY(SYSDATE)
----------------------------- -----------------------------
2019-05-14 15:21:25 tuesday 2019-05-31 15:21:25 friday
下一个
SQL> select next_day(sysdate,'MONDAY') from dual;
NEXT_DAY(SYSDATE,'MONDAY')
-----------------------------
2019-05-20 15:22:00 monday
SQL> select next_day(sysdate,2) from dual;
NEXT_DAY(SYSDATE,2)
-----------------------------
2019-05-20 15:22:38 monday
日期四舍五入
SQL> select sysdate,round(sysdate) from dual;
SYSDATE ROUND(SYSDATE)
----------------------------- -----------------------------
2019-05-14 15:23:01 tuesday 2019-05-15 00:00:00 wednesday
SQL> select sysdate,round(sysdate,'mi') from dual;
SYSDATE ROUND(SYSDATE,'MI')
----------------------------- -----------------------------
2019-05-14 15:26:57 tuesday 2019-05-14 15:27:00 tuesday
SQL> select sysdate,round(sysdate,'DD') from dual;
SYSDATE ROUND(SYSDATE,'DD')
----------------------------- -----------------------------
2019-05-14 15:27:32 tuesday 2019-05-15 00:00:00 wednesday
日期截断
SQL> select sysdate,trunc(sysdate,'yyyy') from dual;
SYSDATE TRUNC(SYSDATE,'YYYY')
----------------------------- -----------------------------
2019-05-14 15:29:11 tuesday 2019-01-01 00:00:00 tuesday
From | To |
---|---|
VARCHAR2 or CHAR | NUMBER |
VARCHAR2 or CHAR | DATE |
Oracle服务器可以在表达式中自动执行数据类型转换。
如,hiredate>‘01-JAN-90’会导致从字符串‘01-JAN-90’到日期的隐式转换。
所以可以隐式地将VARCHAR2或CHAR值转换为表达式中的数字或日期数字类型。
char和varchar的区别
char 长度固定
varchar2 长度动态变化,先判断,再分配,再看超没超过长度
Oracle服务器自动完成下列转换
From | To |
---|---|
NUMBER | VARCHAR2 or CHAR |
DATE | VARCHAR2 or CHAR |
通常,当需要数据类型转换时,Oracle服务器使用表达式规则。
如,grade列是CHAR(2)类型。表达式grade = 2 将导致数值2隐式转换为字符串”2“
TO_CHAR将datetime数据类型转换为format_model指定格式的VARCHAR2数据类型值。
格式模式是描述存储在字符串中的datetime格式的字符文字。
可以使用TO_CHAR函数将日期从其默认格式转换为指定格式。
SQL> select ename,to_char(hiredate,'MM/YY') MON from emp;
ENAME MON
---------- -----
SMITH 12/80
ALLEN 02/81
WARD 02/81
JONES 04/81
MARTIN 09/81
BLAKE 05/81
CLARK 06/81
SCOTT 04/87
KING 11/81
TURNER 09/81
ADAMS 05/87
JAMES 12/81
FORD 12/81
MILLER 01/82
14 rows selected.
YYYY 完整的年份
YEAR 年(英文)
MM 双位数字月份
MONTH 完整的月份名称
MON 月份的三个字母缩写
DY 星期的三个字母缩写
DAY 完整的星期名称
DD 月份的数字(天)
HH24:MI:SS AM 15:45:32 PM
DD “of” MONTH 12 of OCTOBER
ddspth 日期在月份中的位置(如fourteenth)
9 代表一个数字
0 强制显示0
$ 放置一个浮动的美元符号
L 采用浮动本地货币符号
. 打印小数点
, 打印一个逗号作为千位标识符
SQL> select sal,to_char(sal,'$999,999,999.90') s from emp;
SAL S
---------- ----------------
800 $800.00
1600 $1,600.00
1250 $1,250.00
2975 $2,975.00
1250 $1,250.00
2850 $2,850.00
2450 $2,450.00
3000 $3,000.00
5000 $5,000.00
1500 $1,500.00
1100 $1,100.00
950 $950.00
3000 $3,000.00
1300 $1,300.00
14 rows selected.
这里,第一列是数字类型,第二列是字符类型
SQL> select sal,to_char(sal,'$999') s from emp;
SAL S
---------- -----
800 $800
1600 #####
1250 #####
2975 #####
1250 #####
2850 #####
2450 #####
3000 #####
5000 #####
1500 #####
1100 #####
950 $950
3000 #####
1300 #####
14 rows selected.
如果在format model里面添加G、D等,是无效的数字默认类型
TO_NUMBER(char[,'format_model])
TO_DATE(char[,'format_model'])
这些函数适用于任何数据类型,同时也适用于空值
NVL (expr1,expr2)
转换null值为实际的数值
SQL> select nvl2(comm,0,1000),comm from emp;
NVL2(COMM,0,1000) COMM
----------------- ----------
1000
0 300
0 500
1000
0 1400
1000
1000
1000
1000
0 0
1000
1000
1000
1000
14 rows selected.
NVL2 (expr1,expr2,expr3)
如果expr1不是null,转换为expr2,如果expr1是空值,则转换为expr3
# 可以输出字符串
SQL> select ename,sal,nvl2(comm,'sal+comm','sal') income from emp;
ENAME SAL INCOME
---------- ---------- --------
SMITH 800 sal
ALLEN 1600 sal+comm
WARD 1250 sal+comm
JONES 2975 sal
MARTIN 1250 sal+comm
BLAKE 2850 sal
CLARK 2450 sal
SCOTT 3000 sal
KING 5000 sal
TURNER 1500 sal+comm
ADAMS 1100 sal
JAMES 950 sal
FORD 3000 sal
MILLER 1300 sal
14 rows selected.
# 计算收入
SQL> select ename,sal,comm,nvl2(comm,comm+sal,sal) income from emp;
ENAME SAL COMM INCOME
---------- ---------- ---------- ----------
SMITH 800 800
ALLEN 1600 300 1900
WARD 1250 500 1750
JONES 2975 2975
MARTIN 1250 1400 2650
BLAKE 2850 2850
CLARK 2450 2450
SCOTT 3000 3000
KING 5000 5000
TURNER 1500 0 1500
ADAMS 1100 1100
JAMES 950 950
FORD 3000 3000
MILLER 1300 1300
14 rows selected.
NULLIF(expr1,expr2)
比较两个表达式,如果它们相等,返回null;如果它们不相等,返回第一个表达式
SQL> select ename,job,length(ename) l1,length(job) l2,
2 nullif(length(ename),length(job)) l
3 from emp;
ENAME JOB L1 L2 L
---------- --------- ---------- ---------- ----------
SMITH CLERK 5 5
ALLEN SALESMAN 5 8 5
WARD SALESMAN 4 8 4
JONES MANAGER 5 7 5
MARTIN SALESMAN 6 8 6
BLAKE MANAGER 5 7 5
CLARK MANAGER 5 7 5
SCOTT ANALYST 5 7 5
KING PRESIDENT 4 9 4
TURNER SALESMAN 6 8 6
ADAMS CLERK 5 5
JAMES CLERK 5 5
FORD ANALYST 4 7 4
MILLER CLERK 6 5 6
14 rows selected.
COALESCE(expr1,expr2,...,exprn)
返回表达式列表中的第一个非空表达式
COALESCE与NVL相比的优点在于COALESCE可以同时处理交替的多个值。如果第一个表达式非空,则返回这个表达式,对其他的参数进行COALESCE。
SQL> select ename,empno,mgr,comm,
2 coalesce(to_char(comm),to_char(mgr),'No commission and no manager') a
3 from emp;
ENAME EMPNO MGR COMM A
---------- ---------- ---------- ---------- ----------------------------------------
SMITH 7369 7902 7902
ALLEN 7499 7698 300 300
WARD 7521 7698 500 500
JONES 7566 7839 7839
MARTIN 7654 7698 1400 1400
BLAKE 7698 7839 7839
CLARK 7782 7839 7839
SCOTT 7788 7566 7566
KING 7839 No commission and no manager
TURNER 7844 7698 0 0
ADAMS 7876 7788 7788
JAMES 7900 7698 7698
FORD 7902 7566 7566
MILLER 7934 7782 7782
14 rows selected.
如果mgr值不是null,就会显示它,如果mgr值为null,则会显示comm。
如果mgr和comm都为null,则显示“没有佣金,就没有经理”
应用to_char函数时,所有表达式应具有相同的数据类型
在SQL语句中使用IF-THEN-ELSE逻辑,可以使用CASE表达式和DECODE函数。
CASE expr WHEN comparision_expr1 THEN return_expr1
[WHEN comparision_expr2 THEN return_expr2
WHEN comparision_expr3 THEN return_expr3
ELSE else_expr]
END
例:
SQL> select ename,job,sal,
2 case job when 'ANALYST' then 1.5*12*sal
3 when 'SALESMAN' then 1.4*12*sal
4 when 'MANAGER' then 1.3*12*sal
5 else sal end "REVISED_SAL"
6 from emp;
ENAME JOB SAL REVISED_SAL
---------- --------- ---------- -----------
SMITH CLERK 800 800
ALLEN SALESMAN 1600 26880
WARD SALESMAN 1250 21000
JONES MANAGER 2975 46410
MARTIN SALESMAN 1250 21000
BLAKE MANAGER 2850 44460
CLARK MANAGER 2450 38220
SCOTT ANALYST 3000 54000
KING PRESIDENT 5000 5000
TURNER SALESMAN 1500 25200
ADAMS CLERK 1100 1100
JAMES CLERK 950 950
FORD ANALYST 3000 54000
MILLER CLERK 1300 1300
14 rows selected.
SQL> select ename,job,sal,12*sal yesa,
2 case when job in('MANAGER','ANALYST') then 1.5*12*sal
3 when job = 'SALESMAN' then 1.2*12*sal
4 else 12*sal end "NEW"
5 from emp;
ENAME JOB SAL YESA NEW
---------- --------- ---------- ---------- ----------
SMITH CLERK 800 9600 9600
ALLEN SALESMAN 1600 19200 23040
WARD SALESMAN 1250 15000 18000
JONES MANAGER 2975 35700 53550
MARTIN SALESMAN 1250 15000 18000
BLAKE MANAGER 2850 34200 51300
CLARK MANAGER 2450 29400 44100
SCOTT ANALYST 3000 36000 54000
KING PRESIDENT 5000 60000 60000
TURNER SALESMAN 1500 18000 21600
ADAMS CLERK 1100 13200 13200
JAMES CLERK 950 11400 11400
FORD ANALYST 3000 36000 54000
MILLER CLERK 1300 15600 15600
14 rows selected.
SQL> select ename,job,sal,nvl(comm,0),
2 case when (sal+nvl(comm,0)) between 1000 and 1500 then 'BAD'
3 when (sal+nvl(comm,0)) between 1500 and 4000 then 'GOOD'
4 when (sal+nvl(comm,0)) >4000 then 'VERY GOOD'
5 else 'NULL' end "GRADE"
6 from emp;
ENAME JOB SAL NVL(COMM,0) GRADE
---------- --------- ---------- ----------- ---------
SMITH CLERK 800 0 NULL
ALLEN SALESMAN 1600 300 GOOD
WARD SALESMAN 1250 500 GOOD
JONES MANAGER 2975 0 GOOD
MARTIN SALESMAN 1250 1400 GOOD
BLAKE MANAGER 2850 0 GOOD
CLARK MANAGER 2450 0 GOOD
SCOTT ANALYST 3000 0 GOOD
KING PRESIDENT 5000 0 VERY GOOD
TURNER SALESMAN 1500 0 BAD
ADAMS CLERK 1100 0 BAD
JAMES CLERK 950 0 NULL
FORD ANALYST 3000 0 GOOD
MILLER CLERK 1300 0 BAD
14 rows selected.
DECODE(col|expression,search1,result1
[ , search2,result2, ... , ]
[ , default])
DECODE函数对表达式的解码方式类似于各种语言中使用的IF-THEN-ELSE逻辑。
DECODE函数将表达式与每个搜索值进行比较后对其进行解码。
如果表达式与搜索相同,则返回结果。
如果省略默认值,则返回空值,搜索结果的值不匹配任何值。
SQL> select ename,job,sal,
2 decode (job,'ANALYST',1.2*SAL,
3 'MANAGER',1.4*SAL,
4 'SALESMAN',3*SAL,
5 SAL)
6 REVISED_SALARY
7 from emp;
ENAME JOB SAL REVISED_SALARY
---------- --------- ---------- --------------
SMITH CLERK 800 800
ALLEN SALESMAN 1600 4800
WARD SALESMAN 1250 3750
JONES MANAGER 2975 4165
MARTIN SALESMAN 1250 3750
BLAKE MANAGER 2850 3990
CLARK MANAGER 2450 3430
SCOTT ANALYST 3000 3600
KING PRESIDENT 5000 5000
TURNER SALESMAN 1500 4500
ADAMS CLERK 1100 1100
JAMES CLERK 950 950
FORD ANALYST 3000 3600
MILLER CLERK 1300 1300
14 rows selected.
显示部门20的员工,适用的税率:
SQL> select ename,sal,
2 decode(trunc(sal/2000,0),
3 0,'0.00',
4 1,'0.09',
5 2,'0.20',
6 3,'0.30',
7 4,'0.40',
8 5,'0.42',
9 6,'0.44',
10 '0.45') TAX_RATE
11 from emp
12 where deptno = 20;
ENAME SAL TAX_
---------- ---------- ----
SMITH 800 0.00
JONES 2975 0.09
SCOTT 3000 0.09
ADAMS 1100 0.00
FORD 3000 0.09
SELECT group_function(column) , ...
FROM table
[WHERE condition]
[ORDER BY column];
平均
求和
SQL> select avg(sal),sum(sal),max(sal),min(sal) from emp;
AVG(SAL) SUM(SAL) MAX(SAL) MIN(SAL)
---------- ---------- ---------- ----------
2073.21429 29025 5000 800
可以对数字、字符和日期数据类型使用MAX和MIN函数
SQL> select avg(ename) from emp;
select avg(ename) from emp
*
ERROR at line 1:
ORA-01722: invalid number
SQL> select avg(hiredate) from emp;
select avg(hiredate) from emp
*
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected NUMBER got DATE
SQL> select min(hiredate),max(ename) from emp;
MIN(HIRED MAX(ENAME)
--------- ----------
17-DEC-80 WARD
1)count(*)
返回满足select语句条件的表中的行数,包括重复的行和任何列中包含空值的行。如果select语句中包含where子句,count(*)返回满足where子句中条件的行数。
SQL> select count(*) from emp
2 where deptno = 20;
COUNT(*)
----------
5
count(1)与count(*) 的效果一样的,并添加一列值为1的列
SQL> select count(*) from emp;
COUNT(*)
----------
14
SQL> select count(1) from emp;
COUNT(1)
----------
14
2)count(expr)
返回非空值的expr的行数
SQL> select count(comm) from emp;
COUNT(COMM)
-----------
4
3)count(distinct expr)
返回expr非空且不重复的记录数
SQL> select count(distinct job) from emp;
COUNT(DISTINCTJOB)
------------------
5
SQL> select avg(comm) from emp;
AVG(COMM)
----------
550
SQL> select avg(nvl(comm,0)) from emp;
AVG(NVL(COMM,0))
----------------
157.142857
SELECT column,group_function(column)
FROM table
GROUP BY group_by_expression;
SQL> select deptno,avg(sal) from emp
2 group by deptno
3 order by avg(sal);
DEPTNO AVG(SAL)
---------- ----------
30 1566.66667
20 2175
10 2916.66667
在select列表中所有除组函数以外的,所有列都应该包含在group by子句中。(只要写在了select里,就要写在group by里。)
SQL> select job,avg(sal) from emp
2 where job in ('MANAGER','SALESMAN')
3 group by job
4 order by avg(sal);
JOB AVG(SAL)
--------- ----------
SALESMAN 1400
MANAGER 2758.33333
SQL> select deptno,job,sum(sal) from emp
2 group by deptno,job
3 order by deptno;
DEPTNO JOB SUM(SAL)
---------- --------- ----------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
20 ANALYST 6000
20 CLERK 1900
20 MANAGER 2975
30 CLERK 950
30 MANAGER 2850
30 SALESMAN 5600
9 rows selected.
SQL> select avg(sal) m,job from emp
2 group by job
3 having avg(sal) >= 3000
4 order by m;
M JOB
---------- ---------
3000 ANALYST
5000 PRESIDENT
SQL> select deptno ,max(sal) from emp
2 group by deptno
3 having max(sal) >4000;
DEPTNO MAX(SAL)
---------- ----------
10 5000
看表里的部分数据:where
看结果集里的数据:having 一般会跟着group
SELECT column,group_function
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[HAVING group_condition]
[ORDER BY column];
SQL> select max(avg(sal)) ma from emp
2 group by deptno;
MA
----------
2916.66667
不能写部门
SQL> select max(avg(sal)) ma,deptno from emp
2 group by deptno;
select max(avg(sal)) ma,deptno from emp
*
ERROR at line 1:
ORA-00937: not a single-group group function