一、dql
1、基本规则:
(1)对于日期型数据,做 *,/ 运算不合法,可以进行 +, – 运算。比如给日期加一天或减一个月,结果仍为一个日期。两个日期间只能为减法,返回两个日期相差的天数,两个日期间做加法没任何意义。
(2)包含空值(null)的数学表达式计算结果均为空值。
(3)给字段取别名时,别名使用 双引号 括起来(根据双引号里的内容显示),不加双引号时会转为大写。字段与别名间可以使用as关键字,也可使用空格。
(4)oracle中连接字符是 || (也可以使用单行函数concat()), 不是java中的 + 。
(5)字符串使用 单引号 括起来,字符串区分大小写。
(6)distinct用于过滤重复的数据,但不能乱用。
(7)dual为虚表,是一个不存在的表,只为满足select语法,通常用来测试表达式的结果。
2、dql基本关键字
(1)select后跟想查询的列,即最后显示的列。
(2)from后跟的是想查询的表。
(3)where后跟的是查询限制条件。 where后跟的是数字时,可以不用单引号引起,但若为字符串或者日期格式时,需要用单引号引起。
--举例: --打印系统时间 select sysdate from dual; --只会显示一行’helloworld‘。 --输出整张表的信息 select * from lf_employee; --使用字符串,别名,连接符输出表的信息 select employee_name ||' status is ' || employee_status as "name" from lf_employee; --正确使用distinct关键字 select distinct employee_status status, department_id as "id" from lf_employee;
二、条件查询语句、以及排序
1、between … and …
select employee_name, employee_salary salary from lf_employee where employee_salary between 4000 and 7000; --等价于employee_salary >= 4000 and employee_salary <= 7000
2、操作符(and, or, in)
比较操作符:>, < , =, >=, <= , <>(此为不等于,不建议写!=)。 关键字:and(需同时满足条件),or(满足一个条件即可 ),且and优先级大于or。 比较操作符:in(list), not in(list)。 list指集合,表示多个元素,in(list)表示在list取出满足(一个)条件的数据,not in(list)表示取出不符合条件的list数据。 in等价于or的用法。 any与all不能单独使用,其需要与>,<,=,<=,>=等连用。 >any 大于最小值。 >all 大于最大值。 <any 小于最大值。 <all 小于最小值。 all与in的区别在于in是进行值比较,all进行的是范围比较。 select employee_name, employee_salary from lf_employee where employee_salary in(4000, 5000, 6000); --等价于 employee_salary = 4000 or employee_salary = 5000 or employee_salary = 6000 select employee_id, employee_salary from lf_employee where employee_salary > any(1000, 2000) --等价于 employee_salary > 1000
3、like,模糊查询
-- % 表示匹配多个字符(0~n个字符) -- _ 表示匹配单个字符(1个字符) select employee_name, employee_salary from lf_employee t where t.employee_name like '_'; --表示查询名字为单个字符的人 select employee_name, employee_salary from lf_employee t where t.employee_name like '1%'; --表示查询以1开头的所有人名。
4、escape,转义字符
select employee_name, employee_salary from lf_employee t where t.employee_name like '%\_%' escape '\'; --表示查询含有_的名字。将通配符_转义为下划线_。 select employee_name, employee_salary from lf_employee t where t.employee_name like '%_%'; --查询所有名字
5、order by … desc/asc,排序
select employee_id, employee_salary from lf_employee t order by t.employee_salary asc, t.employee_id desc --先按照薪资升序排序,当薪资相同时,按照id降序排序。默认按照升序排序,即asc可不写。
6、distinct
--去除列的重复行。 --对单列去重,则无重复行。 --对多列去重,则多列的组合不重复行。 select distinct employee_salary, employee_id from lf_employee --正确输出结果 select employee_id,distinct employee_salary from lf_employee --报错
三、单行函数
单行函数可以嵌套,执行循序为从内到外。
1、字符函数:
lower(char) --将字符串char转为全大写。 upper(char) --将字符串char转为全小写。 initcap(char) --将字符串char中每个单词的首字母转为大写,其余字母不变。 concat(char1, char2) --将两个字符串拼接。等价于 char1 || char2 。 substr(char, a, b) --截取字符串char,从第a个位置开始,输出b个字符。 length(char) --输出字符串char的长度。 instr(char1, char2) --返回字符串char2首次出现在字符串char1中的位置,不存在则返回0。 lpad(char1, n, char2) --左对齐,显示n位char1,不足的用char2补左边缺失的位。 rpad(char1, n, char2) --右对齐,显示n位char1,不足的用char2补右边缺失的位。 trim('h' from 'hhellohhworldhh') --去除首尾相同的字符 replace('abbbcd', 'bb', 'm') --替换匹配的字符 select upper('king'), lower('king'), initcap('king'), concat('hello', ' world'), substr('hello', 1, 2), length('hello'),instr('hello', 'lo') from dual select lpad(employee_salary, 10, '*'), rpad(employee_salary, 10, '*'), trim('h' from 'hhellohhworldhh'), replace('abbbcd', 'bb', 'm') from lf_employee
2、数字函数
round(m[,n]) --四舍五入,round(45.926, 2) = 45.93 trunc() --截断,trunc(45.926, 2) = 45.92 --注意:若存在第二个参数,第二个参数为正数时,对小数点右边进行操作,为负数时,对小数点左边进行操作。 ceil(n) --取大于或等于n的最小整数 floor(n) --取小于或等于n的最大整数。 mod(m, n) --求余,mod(1600, 300) = 1600%300 = 100 select round(45.926, 2), round(45.926, -1), trunc(45.926, 2), trunc(45.926, -1), mod(1600, 300), mod(300, 1600) from dual
3、日期函数
sysdate --返回当前系统时间,精确到秒。 systimestamp --返回当前系统时间,精确到纳秒。 months_between (date1, date2) --用于计算date1和date2之间有几个月。若date1比date2早,则返回负数,若date1比date2晚,则返回正数,相同则返回0. add_months(date, month) --用于给date加上month个月,当month为小数时,会先被截取(trunc)成整数再参与运算。 next_day(data, char) --表示data之后下一个星期几是哪天。若char表示为数字,即char为1~7时,表示星期日~星期六。 last_day(date) --表示date所在月的最后一天 round(date) --将日期四舍五入 trunc(date) --将日期截断 extract(date from datetime) --从datetime中返回date指定的数据。 greatest(expr1[,expr2[,expr3]]) --为比较函数,返回参数中最大的值。 least(expr1[,expr2[,expr3]]) --为比较函数,返回参数中最小的数。 -- 注意: 比较时,需要参数类型一致。比较时第二个参数会隐式转为第一个参数,若能够转换,则比较,否则会报错。 select sysdate, months_between(sysdate, sysdate + 61) month, add_months(sysdate, 2), next_day(sysdate, 7), last_day(sysdate), trunc(sysdate), round(sysdate) from dual select extract(year from sysdate), add_months(sysdate, 2.8), greatest(sysdate + 1, sysdate -1, sysdate), least(22, 11, 33) from dual
4、转换函数
--隐式转换: date <==> varchar2 <==> number --显示转换: date 通过 to_char() 函数转为 char。 char 通过 to_date() 函数转为 date。 char 通过 to_number() 函数转为 number。 number 通过 to_char() 函数转为 char。 其中: to_char(数字, '格式'), $表示在数字前加$符号,l表示本地货币,.表示小数点, ,表示分隔符。 select to_char(sysdate, 'yyyy"年"mm"月"dd"日"'), to_char(201906.13, 'l999,999.99'), to_char(201906.13, '$999,999.99'), to_char(201906.13, '999,999.99'), to_date('2019.06,13', 'yyyy-mm-dd') from dual
5、通用函数
-- null与任何数字计算结果仍为null。 -- null与字符串连接,null会被当成空格。 -- 在where条件中判断不为null时,需写成is not null,为空写成is null。 nvl(e1, e2) --当e1为null时,使用e2去替换它。 nvl2(e1, e2, e3) --当e1不为null时,返回e2。e1为null时,返回e3。 nullif(e1, e2) --当e1不等于e2时,返回e1。相等时返回null。 coalesce(e1, e2, e3, ..., en) --当e1为null时,执行e2,e2若为null,执行e3,循环执行,直至不为null或执行完。 select nvl(null, 1), nvl(2, 1), nvl2(null, 2, 3), nvl2(1, 2, 3), nullif(1, 1), nullif(1, 2), coalesce(null, '1', '2'), coalesce(null, null, '2') from dual
6、条件表达式
【简单case函数:】 case 参数 when 值1 then 结果1 when 值2 then 结果2 else 结果3 end; 【case搜索函数:(可以进行更多的判断)】 case when 表达式1 then 结果1 when 表达式2 then 结果2 else 结果3 end; 注:case函数只返回第一个符合条件的值。 【decode表达式:】 decode(参数, 值1, 结果1, 值2, 结果2, 结果3) select employee_salary salary, case employee_salary when 5000 then 3000 when 7000 then 4000 else 5000 end as "case salary", decode(employee_salary, 5000, 3000, 7000, 4000, 5000) "decode salary" from lf_employee
四、多行函数(聚合函数、组函数、集合函数)
1、聚合函数用于统计数据,聚合函数对一组值进行计算并返回单一的值。
2、聚合函数不能单独写在where中,因为where是对每行数据进行判断,而聚合函数是对所有数据进行操作。聚合函数一般与group by连用。
3、聚合函数忽略空值(null)。
假如:现有10个人,但只有4人有奖金,如果采用聚合函数直接进行计算的话,得到的结果是 (4人奖金和/4人),因为会忽略空值(即空值不参与聚合函数运算)。 若想实现(4人奖金和/10人),可按照如下写法: select avg(nvl(salary, 0)) from emp; 这个查询语句表示,当salary为null时,将其赋值为0,这样就可以让其参与聚合函数的运算。 --max(列名) 求某列的最大值 , min(列名) 求某列的最小值。 --avg(列名) 求某列的平均值, sum(列名) 求某列的总和。 --count(列名) 求某列非空的记录数。 --count(*) 统计表中的(非空)记录数。 select max(employee_salary), min(employee_salary), avg(employee_salary), sum(employee_salary),count(employee_salary), count(*) from lf_employee
五、分组函数(group by , having)
1、group by一般写在from之后,用于分组。
2、若group by中出现多列,那么将列组合看成 分组的依据。
3、若select中出现了非组函数列(非max,min等),那么这些列必须存在group by中,否则或报错,但group by中出现了非组函数列,select中可以不存在。
比如:employee_status(非组函数列)存在select中,而不在group by中,则会报错。 select employee_id,employee_status,max(employee_salary), min(employee_salary) from lf_employee group by employee_id --错误写法,会报错 select employee_id,employee_status,max(employee_salary), min(employee_salary) from lf_employee group by employee_id, employee_status --正确写法
4、having子句不能单独存在,必须跟在group by后面,其是对分组结果的进一步限制。having是在第一次检索完成后,进行第二次的检索。
select max(employee_salary), count(employee_salary) from lf_employee group by employee_salary select max(employee_salary), count(employee_salary) from lf_employee group by employee_salary having(employee_salary) > 2000
六、数据类型
1、常用数据类型:
number、 char、varchar2、date、timestamp、 long、clob。
--举例: create table emp{ --创建一个表 id number(4); --表示四位整数 name varchar2(20); --最长20个字节的变长字符串 gender char(1); --定长1个字节的字符串 sal number(6, 2); --表示四位整数,两位小数 hiredate date; --定义日期类型 }
2、number(oracle独有类型)
number指数字类型, 格式: number(p, s), p指数字的总位数(p取值为1~38),s指小数点后面的位数。 number类型和java数据类型对应关系: number类型长度 java数据类型 n>18 java.math.bigdecimal 10<=n<=18 java.lang.long 1 <=n<=9 java.lang.integer 举例: emp表中的sal列定义为: sal number(6, 2),则表示为整数部分最大为4位,小数部分最大为2位,即表示的最大值为9999.99 。
3、char、varchar2
char表示固定长度的字符串。易造成空间的浪费,但索引效率高。 格式: char(n),固定占用n个字节(不是字符),最大为2000字节。 varchar2 相当于 其他数据库的 varchar,表示可变长的字符串。varchar2比char空间利用率高,但性能差。 格式: varchar2(n),最多占用n个字节,最大值为4000字节。
4、date、timestamp
date用于定义日期的数据。长度为7个字节。 对于日期数据,可以定义为date类型,也可以定义为varchar2(30)。 sysdate,本质为oracle的内部函数,用于返回当前的系统时间,精确到秒。 timestamp用于保存日期时间,相比于date,timestamp可以保存更精确的值,精确到纳秒。 其长度为7字节或者11字节。长度为7字节时,与date相同。长度为11字节时,第8字节至第11字节内部采用整型运算,用于保存纳秒值。
5、long与club类型
long是varchar2的加长版,也是变长字符串,最多能存2gb的字符串数据。每个表最多只允许存在一个long列,且不能为主键、不能建立索引、不能出现在查询语句中。 club:是oracle推荐的, 建议用club代替long,存储定长或变长字符串,最多4gb。