数据库就是指存放数据的仓库。
目前主流的数据库有:Oracle、SQL Server、MySql、DB2、..
- 终端输入 sqlplus
- show user; # 查看当前账号
create tablespace practice -- 表示创建表空间,名字为practice
datafile 'd:\practice.dbf' -- 表示对应d盘下名字为pratice.dbf的文件
size 10M; -- 表示表空间的大小为10Mb
drop tablespace practice -- 表示删除名字为practice的表空间
including contents and datafiles; -- 表示同时删除里面的内容以及对应的文件
create user xiaomage -- 表示创建用户,名字为 xiaomage
identified by 123456 -- 表示密码设置为 123456
default tablespace practice; -- 表示默认表空间为 practicedrop user xiaomage; -- 表示删除用户 xiaomage
grant create view to xiaomage; -- 表示授予创建视图的权限给xiaomage
grant connect,resource to xiaomage; -- 表示授予连接、建表等权限给xiaomage
revoke create view from xiaomage; -- 表示撤销xiaomage创建视图的权限
revoke connect,resource from xiaomage; -- 表示撤销xiaomage连接、建表等权限
exit; -- 表示退出当前账户,使用xiaomage账户重新登录
在Java语言中的基本数据类型有:byte、short、int、long、float、double、char、boolean类型。
在SQL语言中的常用数据类型有:数值类型、字符类型、日期类型。
number(n) - 表示可以描述n位数字,如:number(2)等
number(n,m) - 表示总共描述n位数字,但小数点后有m位数字,如:number(3,2)等char(n) - 表示字符串的长度为n,若填不满则使用空格补齐
varchar2(n) - 表示字符串的长度为n,若填不满则自动缩小长度date - 用于描述日期类型,可以描述年月日时分秒信息。
- create table 表名(
列名1 数据类型,
列名2 数据类型,
...
);
如:
create table person(
name varchar2(20), -- 姓名
age number(3), -- 年龄
sex char(3) -- 性别
);
-- 删除表格中列的格式
alter table 表名 drop column 列名;
如:
-- 表示修改person表的方式为删除名字为sex的列
alter table person drop column sex;
-- 增加表格中列的格式
alter table 表名 add 列名 数据类型;
如:
-- 实现向person表中增加名字为sex类型为3个字节字符类型的列
alter table person add sex char(3);
-- 修改表格中列名的格式
alter table 表名 rename column 列名 to 新列名;
如:
-- 实现将person表中名字为sex的列名修改为gender
alter table person rename column sex to gender;保留字段的使用:
create table ps(
pid varchar2(8),
title varchar2(20),
price number(8,2),
gid number(2),
des CLOB,
count number(6),
baoliu1 varchar2(20),
baoliu2 varchar2(20),
baoliu3 varchar2(20)
);
- drop table 表名;
如:
-- 表示删除名字为p的表
drop table p;
- insert into 表名 [(列名1, 列名2, ...)] values(数据1, 数据2, ...);
如:
-- 实现向person表中插入数据 '武志伟' 18 '男'
insert into person (name, age, gender) values('武志伟', 18, '男');
-- 实现向person表中插入数据 '苍老师' '女'
insert into person (name, gender) values('苍老师', '女');
-- 实现向person表中插入数据 '薛宇宸' 17 '男'
insert into person values('薛宇宸', 17, '男');
- update 表名 set 列名 = 更新后的新值 [where 条件];
如:
-- 实现将person表中所有人的年龄都改为18
update person set age = 18;
-- 实现将person表中名字为'武志伟'的年龄改为16
update person set age = 16 where name = '武志伟';
- delete [from] 表名 [where 条件];
如:
-- 实现将person表中名字为'苍老师'的记录删除
delete from person where name = '苍老师';
-- 实现将person表中所有记录删除
delete from person;
- desc 表名; -- 表示查看表结构,也就是查看该表的所有字段以及类型等信息
- select 列名1,列名2,... from 表名;
如:
-- 查询员工表中所有员工的编号
select id from s_emp;
-- 查询员工表中所有员工的编号、名字以及薪水
select id,first_name,salary from s_emp;- -- 查询员工表中所有字段的简化写法
select * from s_emp;
- -- 查询员工表中每个员工加500元过节费后的薪水
select salary,salary+500 from s_emp;
-- 查询员工表中每个员工减200元后的薪水
select id,first_name,salary,salary-200 from s_emp;
-- 查询员工表中所有员工的年薪
select first_name,salary,salary*16 from s_emp;
-- 查询员工表中所有员工的日薪
select first_name,salary,salary/22 from s_emp;
-- 查询员工表中9对2取余的结果
select first_name,salary,mod(9,2) from s_emp;
-- 查询员工表中所有员工的年薪,并将列名设置为 '年薪'
select salary, salary*16 as 年薪 from s_emp;
-- as 关键字可以省略
select salary, salary*16 年薪 from s_emp;
-- 希望在年薪中间加上 空格
select salary, salary*16 年 薪 from s_emp; -- error
-- 更正上述的错误
select salary, salary*16 "年 薪" from s_emp;
-- 查询员工表中所有员工的年薪,并将列名设置为'Income'
select salary, salary*16 Income from s_emp;
-- ''和""中括起来的内容是区分大小写的
select salary, salary*16 "Income" from s_emp;注意:
a.当别名中需要区分大小写,或者有空格这类特殊字符时,需要使用 双引号 括起来
b.当需要描述字符串数据时,就需要使用 单引号 括起来;
- -- 查询员工表中所有员工的姓名
select last_name, first_name from s_emp;- -- 将姓名拼接起来组成一个整体,并起别名为 "姓 名"
select last_name||first_name "姓 名" from s_emp;- -- 将姓名之间使用字符串'-'拼接起来
select last_name||'-'||first_name "姓 名" from s_emp;- -- 将姓名之间使用字符串'_'拼接起来
select last_name||'_'||first_name "姓 名" from s_emp;- -- 将姓名之间使用单引号拼接起来
select last_name||'''||first_name "姓 名" from s_emp; -- error- -- 单引号代表转义字符 ''表示显示一个单引号
select last_name||''''||first_name "姓 名" from s_emp;
select last_name||''''''||first_name "姓 名" from s_emp;
select last_name||''''||''''||first_name "姓 名" from s_emp;- -- 查询常量列
select '兄弟连' "公司 名称" from s_emp;
- select 列名1 [as] 列的别名1, 列名2 [as] 列的别名2, ... from 表名 where 查询的条件表达式;
= 等于 <> 不等于 < 小于 <= 小于等于 > 大于 >= 大于等于
注意:
sql语句中没有赋值的概念,只有=表示等于的含义。
如:
-- 查询员工表中薪水等于800的员工编号,名字以及薪水信息
select id, first_name, salary from s_emp
where salary = 800;
-- 查询员工表中薪水不等于800的员工编号,名字以及薪水信息
select id, first_name, salary from s_emp
where salary <> 800;
-- 查询员工表中薪水大于1000的员工编号,名字以及薪水信息
select id, first_name, salary from s_emp
where salary > 1000;
-- 查询员工表中薪水小于等于800的员工编号,名字以及薪水信息
select id, first_name, salary from s_emp
where salary <= 800;
and(&&) 并且 or(||) 或者 not(!) 取反
如:
-- 查询员工表中薪水大于等于1000并且部门编号为41的员工信息
select id, first_name, salary, dept_id from s_emp
where salary >= 1000 and dept_id = 41;
select id, first_name, salary, dept_id from s_emp
where salary >= 1000 && dept_id = 41; -- error
-- 查询员工表中薪水大于等于1000 并且 部门编号不为41的员工信息
select id, first_name, salary, dept_id from s_emp
where salary >= 1000 and dept_id <> 41;
select id, first_name, salary, dept_id from s_emp
where salary >= 1000 and not dept_id = 41;
-- 查询员工表中薪水小于800 或者 部门编号为42的员工信息
select id, first_name, salary, dept_id from s_emp
where salary < 800 or dept_id = 42;
-- 查询员工表中薪水小于1000 并且 部门编号为31 或者 42
select id, first_name, salary, dept_id from s_emp
where salary < 1000 and dept_id = 31 or dept_id = 42; -- 优先级
select id, first_name, salary, dept_id from s_emp
where salary < 1000 and (dept_id = 31 or dept_id = 42); -- 提高优先级
-- 见识一下极限条件
select * from s_emp where 1 = 1; -- 全部查询完毕
select * from s_emp where 1 != 1; -- 没有报错,但一条记录都没有查询出来
select * from s_emp where 1 <> 1; -- 推荐该运算符
-- 查询员工的日薪,last_name = 'Dancs';
select last_name, salary, salary/21 from s_emp
where last_name = 'dancs'; -- 没有查询到
select last_name, salary, salary/21 from s_emp
where last_name = 'Dancs'; -- 可以查询到注意:
a.and运算符的优先级高于or,该运算符会被优先处理
b.在where子句中的条件是从右向左依次判断的,
对于and运算符来说,应该尽可能将条件更容易为假的放在右边;
对于or运算符来说,应该尽可能将条件更容易为真的放在右边;
- between ... and 表示在...和...之间,该语句表达的是闭区间。
如:
-- 查询员工表中薪水范围在800到1000之间的所有员工编号、名字以及薪水信息
select id, first_name, salary from s_emp
where salary between 800 and 1000;
select id, first_name, salary from s_emp
where salary >= 800 and salary <= 1000;
select id, first_name, salary from s_emp
where salary > 800 and salary < 1000;
-- 查询员工表中薪水范围不在1000到1300之间
select id, first_name, salary from s_emp
where salary not between 1000 and 1300;
select id, first_name, salary from s_emp
where salary < 1000 or salary > 1300;-- 常见的错误,不会报错但啥也查不到
select id, first_name, salary from s_emp
where salary between 1000 and 800;
select id, first_name, salary from s_emp
where salary >= 1000 and salary <= 800;
is null - 用于判断是否为空
is not null - 用于判断是否不为空
如:
-- 查询员工表中提成为空的员工编号,名字以及提成信息
select id, first_name, commission_pct from s_emp -- 查询有结果
where commission_pct is null;
-- 查询员工表中提成不为空的员工编号,名字以及提成信息
select id, first_name, commission_pct from s_emp -- 查询有结果
where commission_pct is not null;
-- 查询员工表中所有员工的薪水,加上提成的薪水
select salary, salary+commission_pct from s_emp; -- 查询结果有问题
nvl(参数1, 参数2) - 若参数1不为空,则函数的结果就是参数1的数值
- 若参数1为空,则函数的结果就是参数2的数值
如:
-- 查询员工表中所有员工的薪水,加上提成的薪水
select salary, salary+nvl(commission_pct, 0) from s_emp;注意:
任何数据和空运算的结果还是空!
- select [distinct] 列名1 [as] 列的别名1, 列名2 [as] 列的别名2, ... from 表名
where 查询的条件表达式;
如:
-- 查询员工表中薪水大于800的员工编号,名字以及薪水信息
select id, first_name, salary from s_emp
where salary > 800;
-- 查询员工表中薪水大于800的薪水等级,去掉重复的薪水
select distinct salary from s_emp
where salary > 800;
-- 查询员工表中薪水、领导的编号信息
select salary, manager_id from s_emp;
-- 查询员工表中去重之后的薪水和领导编号
-- 只有薪水和领导编号都相同时才能去重
select distinct salary, manager_id from s_emp;
按照范围进行查找
between ... and ... -- 表示查询在...和...之间的内容,而且是闭区间
in ... -- 表示查询在...里面的任何内容
not in ... -- 表示查询不在...里面的数据内容
如:
-- 查询员工表中部门编号在41和42之间的员工编号、员工名字以及部门编号
select id, first_name, dept_id from s_emp
where dept_id between 41 and 42;
select id, first_name, dept_id from s_emp
where dept_id >= 41 and dept_id <= 42;
select id, first_name, dept_id from s_emp
where dept_id in(41, 42);
-- 查询员工表中所有部门编号的员工编号、员工名字以及部门编号
select id, first_name, dept_id from s_emp;
-- 查询员工表中所有部门编号并且进行去重处理
select distinct dept_id from s_emp;
-- 查询员工表中部门编号在41和42之间的员工编号、员工名字以及部门编号
-- 由于not in使用太复杂而且效率较低,因此以后的开发中尽量不要使用
select id, first_name, dept_id from s_emp
where dept_id not in(43, 34, 44, 31, 35, 50, 45, 32, 33, 10);
like ... -- 表示像...,通常进行模糊查询,搭配使用的通配符有:
_ -- 表示任意一个字符
% -- 表示任意多个字符
not like ... (了解)
如:
-- 查询员工表中名字使用B开头的员工编号和员工名字
select id, first_name from s_emp
where first_name like 'b%'; -- 查询不到数据
select id, first_name from s_emp
where first_name like 'B%';
-- 查询员工表中名字里含有'德'的员工编号和员工名字
select id, first_name from s_emp
where first_name like '%德%';
-- 查询员工表中名字末尾是'德'前面只有一个字符的员工编号和员工名字
select id, first_name from s_emp
where first_name like '_德';
-- 查询员工表中名字末尾是'克'的员工编号和员工名字
select id, first_name from s_emp
where first_name like '%克';
-- 查询员工表中名字中含有'拉'的员工编号和员工名字
select id, first_name from s_emp
where first_name like '%拉%';
-- 查询员工表中名字末尾是'拉'的员工编号和员工名字
select id, first_name from s_emp
where first_name like '%拉';-- 向员工表中插入数据内容 '1001' '_欣霖'
insert into s_emp (id, first_name) values('1001', '_欣霖');
-- 查询员工表中使用'_'为开头的员工编号和员工名字
select id, first_name from s_emp
where first_name like '_%'; -- 其中_被当做通配符处理,查询到所有数据
-- 尝试使用单引号进行转义
select id, first_name from s_emp
where first_name like''_%'; -- error: 无效的字符,单引号无法转义_
-- 实现对_进行转义
-- 表示将'\'当做转义字符来转义'\'后面字符的含义
select id, first_name from s_emp
where first_name like '\_%' escape '\';
-- 表示将'#'当做转义字符来转义'\'后面字符的含义
select id, first_name from s_emp
where first_name like '#_%' escape '#';-- 查询“山东”的学生姓名、电话、住址 student学生表
select studentname, phone, address from student
where address = '山东'; -- 语句无误,查不到数据
select studentname, phone, address from student
where address like '山东%';-- 查询名称中含有“p”字母的科目信息 subject课程表
select * from subject
where subjectname like '%p%';-- 查询电话中以“1387”开头的学生信息 student学生表
select * from student
where phone like '1387%';-- 查询姓姜的,单名的学生信息 student学生表
select * from student
where studentname like '姜_';
-- 查询学号为S1101004的指定1,2,3科目考试成绩 result成绩表
select studentno, studentresult, subjectid from result
where studentno = 'S1101004' and subjectid in (1, 2, 3);
select [distinct] 字段名1 [as 别名1], 字段名2 [as 别名2], ...
from 表名
[where 查询的条件];
[order by 字段/别名/位置编号 asc/desc] ; -- 默认是从小到大排序(asc)
如:
-- 查询员工表中所有员工的名字和薪水,并且按照薪水进行排序
select first_name, salary from s_emp
order by salary; -- 默认按照升序排列,而且null放在最后
select first_name, salary from s_emp
order by salary asc; -- asc可以写也可以不写
-- 查询员工表中所有员工的名字和薪水,要求按照薪水进行降序排列
select first_name, salary from s_emp
order by salary desc; -- null放在最前面,影响体验度
-- 若希望将null值放在后面
select first_name, salary from s_emp
order by salary desc nulls last;
-- 查询员工表中所有员工的名字和薪水,将薪水起别名为 sal并按照sal进行升序
select first_name, salary sal from s_emp
order by sal;
-- 查询员工表中所有员工的名字和年薪,并按照年薪进行升序排列
select first_name, salary, salary*16 "年 薪" from s_emp
order by "年 薪";
-- 查询员工表中所有员工的名字和薪水,并根据位置编号(下标)进行升序排序
select first_name, salary from s_emp
order by 0; -- error,位置编号从1开始
select first_name, salary from s_emp
order by 1; -- 表示按照位置编号1(名字)开始排序
select first_name, salary from s_emp
order by 2; -- 表示按照位置编号2(薪水)开始排序
select first_name, salary from s_emp
order by 3; -- error,查询的列数总共2列
select first_name, salary, salary*16 from s_emp
order by 3; -- 表示按照年薪排序-- 查询员工表中所有员工的部门编号,薪水,要求先按照部门编号进行降序排序
select dept_id, salary from s_emp
order by dept_id desc;
-- 查询员工表中所有员工的部门编号,薪水,先按照部门编号降序,再按照薪水升序
select dept_id, salary from s_emp
order by dept_id desc, salary;
-- 查询员工表中所有员工的部门编号,薪水,先按照部门编号降序,再按照薪水降序
select dept_id, salary from s_emp
order by dept_id desc, salary desc; -- 多字段排序时,需要写多个desc
-- 先按照部门编号降序,再按照薪水降序,再按照员工编号升序
select dept_id, salary, id from s_emp
order by dept_id desc, salary desc, id asc;
- 如:
-- 实现计算字符串'hello'的长度
select length('hello') 字符串长度 from dual;
-- 实现将字符串'hello'转换为大写
select upper('hello') 转换为大写 from dual;
-- 实现将字符串'HELLO'转换为小写
select lower('HELLO') 转换为小写 from dual;
-- 实现将字符串'hello'中的首字母转换为大写
select initcap('hello') 首字母转大写 from dual;
-- 实现将字符串'hello'中从下标2开始取出3个字符,下标从1开始
select substr('hello', 2, 3) 获取子串 from dual; -- ell
-- 实现将字符串'hello'和'world'进行拼接
select concat('hello', 'world') 拼接字符串 from dual; -- helloworld
-- 实现字符串中内容的替换,将'e'替换为'E'
select replace('hello', 'e', 'E') 字符串替换 from dual; -- hEllo
-- 实现字符串中子串的查找,查找'l'第一次出现的下标位置
select instr('hello', 'l') 子串查找 from dual; -- 3
-- 实现去除字符串中两端的空白字符
select length(trim(' hello ')) 去除空白字符 from dual;
-- 查询数据3.1415926保留3位小数并四舍五入后的结果
select round(3.1415926, 3) from dual; -- 3.142
-- 查询数据保留1位小数并四舍五入后的结果
select round(3.1415926, 1) from dual; -- 3.1
-- 查询数据保留0位小数,也就是取整数并四舍五入的结果
select round(3.1415926, 0) from dual; -- 3
-- 查询数据保留-1位小数,也就是将整数的最后一位进行四舍五入
select round(13.1415926, -1) from dual; -- 10-- 查询数据3.1415926保留3位小数, 没有四舍五入后的结果
select trunc(3.1415926, 3) from dual; -- 3.141
-- 查询数据保留1位小数并没有四舍五入后的结果
select trunc(3.1415926, 1) from dual; -- 3.1
-- 查询数据保留0位小数,也就是取整数并没有四舍五入的结果
select trunc(3.1415926, 0) from dual; -- 3
-- 查询数据保留-1位小数,也就是将整数的最后一位不进行四舍五入
select trunc(13.1415926, -1) from dual; -- 10
to_date() - 主要用于将字符串类型转换为日期类型后插入到数据库中;
to_char() - 主要用于将日期类型转换为字符串类型后从数据库中取出数据;
如:
-- 查询当前系统时间
select sysdate from dual;
-- 查询当前系统时间的昨天
select sysdate-1 from dual;
-- 查询当前系统时间的明天
select sysdate+1 from dual;
-- 查询员工表中员工的编号、名字以及入职日期,要求入职日期按照年月日
select id, first_name, start_date from s_emp;
select id, first_name, to_char(start_date, 'yyyy-mm-dd') 入职日期 from s_emp;
-- 向员工表中插入编号为'1005', '张斌',to_date('2019-07-23', 'yyyy-mm-dd')
insert into s_emp (id, first_name, start_date) values('1005', '张斌',to_date('2019-07-23', 'yyyy-mm-dd'));-- 查询当前系统时间的下一个月
select add_months(sysdate, 1) from dual;
-- 查询当前系统时间的下两个月
select add_months(sysdate, 2) from dual;
-- 查询当前系统时间的上一个月
select add_months(sysdate, -1) from dual;
-- 查询当前系统时间+1个月+1天+1小时+1分钟后的时间
select to_char(add_months(sysdate, 1) + 1 + 1/24 + 1/24/60, 'yyyy-mm-dd hh24:mi:ss') 处理后的时间 from dual;-- 查询当前系统时间并按照dd进行截取,也就是dd后面的数据全部丢弃
select to_char(trunc(sysdate, 'dd'), 'yyyy-mm-dd hh24:mi:ss') from dual;
-- 查询当前系统时间并按照mm进行截取
select to_char(trunc(sysdate, 'mm'), 'yyyy-mm-dd hh24:mi:ss') from dual;
-- 查询当前系统时间并按照yyyy进行截图
select to_char(trunc(sysdate, 'yyyy'), 'yyyy-mm-dd hh24:mi:ss') from dual;
练习讲解:
-- 求当前月份的最后一分钟0秒表示的date数据
-- 2019-7-31 23:59:00
select to_char(trunc(add_months(sysdate, 1), 'mm')-1/24/60, 'yyyy-mm-dd hh24:mi:ss') from dual;-- 求下个月的第三天的倒数十分钟0秒表示的date数据
-- 2019-8-03 23:50:00
select to_char(trunc(add_months(sysdate, 1), 'mm')+3 - 1/24/60*10, 'yyyy-mm-dd hh24:mi:ss') from dual;-- 查询s_emp表格(id,last_name,start_date),按照start_date排序
-- 查询的条件为: 入职日期在2018年1月1日 到2018年12月31日
select id, last_name, start_date from s_emp
where start_date between to_date('2018-01-01', 'yyyy-mm-dd')
and to_date('2018-12-31', 'yyyy-mm-dd')
order by start_date;
-- 查询员工表中部门在31、32、33的员工编号、员工姓名以及部门编号信息
select id, last_name||first_name "姓 名", dept_id from s_emp
where dept_id in (31, 32, 33);-- 查询成绩表中学生编号、课程编号以及学生成绩信息,要求按照学生编号
-- 进行降序排列,若学生编号一样按照课程编号降序,
-- 若课程编号一样按照成绩升序排序
select id, subjectid, studentresult from result
order by id desc, subjectid desc, studentresult asc;-- 查询s_emp表所有first_name包含b或B的员工,显示id、first_name、salary信息
select id, first_name, salary from s_emp
where first_name like '%b%' or first_name like '%B%';
select id, first_name, salary from s_emp
where lower(first_name) like '%b%';-- 显示s_emp表中first_name中4个字符以后的内容
select first_name, substr(first_name, 5, length(first_name)-4) from s_emp;-- 查询今天过生日的员工信息,假设入职日期就是出生日期
select id, first_name, to_char(start_date, 'yyyy-mm-dd') from s_emp
where to_char(start_date, 'mm-dd') = to_char(sysdate, 'mm-dd');
常用的聚合(多行)函数
所谓单行函数主要指 单条数据传入给该函数后处理的结果还是单条数据;
所谓聚合(多行)函数主要指 多条数据传入给函数后处理的结果是单条数据
常用的聚合函数有:
sum() - 主要用于实现多个数据累加和的计算,只能计算数值类型的数据;
avg() - 主要用于实现多个数据平均值的计算,只能计算数值类型的数据;
max() - 主要用于实现多个数据最大值的计算,可以计算任意类型的数据;
min() - 主要用于实现多个数据最小值的计算,可以计算任意类型的数据;
count() - 主要用于实现多个数据的计数,可以计算任意类型数据,如:count(*)
如:
-- 查询员工表中所有员工的总薪水信息
select sum(salary) 人力成本 from s_emp;
-- 查询员工表中所有员工的平均薪水信息
select avg(salary) 平均薪水 from s_emp;
-- 查询员工表中所有员工的最高薪水信息
select max(salary) 最高薪水 from s_emp;
-- 查询员工表中资历最小的员工信息
select max(start_date) 资历最小 from s_emp;
-- 查询员工表中的最低薪水
select min(salary) 最低薪水 from s_emp;
-- 查询员工表中的资历最老的员工信息
select min(start_date) 资历最老 from s_emp;
-- 查询员工表中的员工数量
select count(*) 员工数量 from s_emp;练习:
-- 查询成绩表中所有学员的总成绩
select sum(studentresult) 总成绩 from result;
-- 查询成绩表中所有学员成绩的平均成绩
select avg(studentresult) 平均成绩 from result;
-- 查询成绩表中所有学员的最高成绩
select max(studentresult) 最高分 from result;
-- 查询成绩表中所有学员的最低成绩
select min(studentresult) 最低分 from result;
-- 查询成绩表中所有学员的成绩个数
select count(*) 成绩个数 from result;
-- 查询员工表中所有员工提成的平均值
select round(avg(nvl(commission_pct, 0)), 2) from s_emp;
group by子句
select 字段名1 [as 别名1], 字段名2 [as 别名2], ... from 表名
[where 条件表达式]
[group by 字段名1, 字段名2]
[order by 字段名/别名/位置编号];如:
-- 查询学生表中每个年级的总人数,显示年级编号和总人数
select gradeid, count(*) from student
group by gradeid
order by count(*);注意:
select后面允许出现的字段只能是group by后面跟的字段以及聚合函数。练习:
-- 查询每门课程的平均成绩,每...就表示按照...分组 result成绩表
select subjectid 课程编号, round(avg(studentresult),2) 平均分 from result
group by subjectid
order by avg(studentresult);
-- 查询学生表中每个年级中每种性别的总人数,,并按照年级排序
select gradeid, sex, count(*) from student
group by gradeid,sex
order by gradeid;-- 查询员工表中每个部门的员工人数,并按照人数进行排序
select dept_id, count(*) from s_emp
group by dept_id
order by count(*);
select 字段名1 [as 别名1], 字段名2 [as 别名2], ... from 表名
[where 条件表达式]
[group by 字段名1, 字段名2]
[having 条件表达式]
[order by 字段名/别名/位置编号];如:
-- 查询学生表中每个年级的总人数,并将总人数超过18人的年级编号显示出来
select gradeid, count(*) from student
where count(*) > 18
group by gradeid; -- error: where子句中不能使用聚合函数select gradeid, count(*) from student
group by gradeid
having count(*) > 18 -- having子句可以对分组的结果再次筛选
order by count(*);练习:
-- 查询每个年级的总课时,并升序排列 (subject表)
select gradeid, sum(classhour) from subject
group by gradeid
order by sum(classhour) asc;-- 查询每个学员的平均分(result表)
select studentno, round(avg(studentresult), 2) from result
group by studentno;-- 查询每门课程的平均分,并降序排列(result表)
select subjectid, round(avg(studentresult), 2) from result
group by subjectid
order by avg(studentresult) desc;-- 查询每个学生的总分,并降序排列(result表)
select studentno, sum(studentresult) from result
group by studentno
order by sum(studentresult) desc;-- 查询每门课程的平均分超过60的课程信息
select subjectid, round(avg(studentresult), 2) from result
group by subjectid
having avg(studentresult) > 60;-- 查询员工表中每个部门的总人数超过2个人的部门信息
select dept_id, count(*) from s_emp
group by dept_id
having count(*) > 2;-- 查询员工表中每个部门的平均薪水超过1000元的部门信息
select dept_id, round(avg(salary), 2) from s_emp
group by dept_id
having avg(salary) > 1000;
Select查询语句的执行流程:
from 表名 => where子句 => group by分组 => having子句 => select取出数据
=> order by子句
如:
-- 从学生表中查询比'崔今生'年龄小的学生信息,也就是出生日期比'崔今生'大
-- 首先从学生表中查询名字为'崔今生'的出生日期
select borndate from student
where studentname = '崔今生'; -- 查询结果: 1990-1-5-- 其次从学生表中查询出生日期比'崔今生'出生日期大的学生信息
select borndate from student
where borndate > to_date('1990-01-05', 'yyyy-mm-dd');
-- 使用子查询来实现上述功能
select borndate from student
where borndate > (select borndate from student
where studentname = '崔今生');练习:
-- 使用子查询在员工表中查询与'埃琳娜'在同一个部门的员工信息
-- 首先查询员工表中'埃琳娜'所在的部门编号
select dept_id from s_emp
where first_name = '埃琳娜'; -- 查询结果:41-- 其次查询员工表中与'埃琳娜'所在部门编号相等的员工信息
select * from s_emp
where dept_id = 41;-- 合并为子查询语句
select * from s_emp
where dept_id = (select dept_id from s_emp
where first_name = '埃琳娜');案例讲解:
-- 查询'JavaSE'课程并且考了100分的学生信息
select * from student
where studentno = 'S1101019';-- 从课程表中查询'JavaSE'课程对应的课程编号
select subjectid from subject
where subjectname = 'JavaSE'; -- 查询结果: 1-- 从成绩表中查询'JavaSE'课程并且考了100分的学生编号
select studentno from result
where subjectid = 1 and studentresult = 100; -- 查询结果:S1101019-- 合并上述代码
select * from student
where studentno = (select studentno from result
where subjectid = (select subjectid from subject
where subjectname = 'JavaSE' ) and studentresult = 100 );练习:
-- 查询“青铜”阶段开设的课程
-- 该需求涉及到 grade阶段表 和 subject课程表,表之间通过 gradeid 字段关联
-- 先由阶段名称可以查询到阶段编号,再由阶段的编号得到课程名称
select subjectname from subject
where gradeid = (select gradeid from grade
where gradename = '青铜');-- 查询参加最近一次“HTML和CSS网页技术”考试成绩的最高分和最低分
-- 该需求涉及到 subject课程表 和 result成绩表,表之间通过subjectid字段关联
-- 先由课程名称可以查询到课程编号,再由课程编号可以查询到考试成绩和
-- 最近一次考试的时间,再根据考试成绩得到最高分和最低分
select max(studentresult) 最高分, min(studentresult) from result
where subjectid = ( select subjectid from subject
where subjectname = 'HTML和CSS网页技术')
and examdate = ( select max(examdate) from result
where subjectid = ( select subjectid from subject
where subjectname = 'HTML和CSS网页技术'));案例讲解:
-- 查询'JavaSE'课程考试成绩不及格的学生名称
-- 该需求涉及到 subject课程表 和 result成绩表 以及 student学生表
-- 其中subject表和result表之间采用 subjectid 字段关联
-- 其中result表和student表之间采用 studentno 字段关联
-- 先由课程名称可以查询到课程编号,再由课程编号以及考试成绩可以查询到学号
-- 再根据学生的学号可以得到学生的名字
select studentname from student
where studentno = ( select studentno from result
where studentresult < 60 and subjectid =(select subjectid from subject
where subjectname = 'JavaSE' )); -- error: 有多个人不及格
-- 当子查询的结果有多个数据内容时,则将 = 换成in即可
select studentname from student
where studentno in ( select studentno from result
where studentresult < 60 and subjectid =(select subjectid from subject
where subjectname = 'JavaSE' ));-- 当子查询的结果有多个数据内容时,则在 = 的后面加上any关键字即可
select studentname from student
where studentno = any ( select studentno from result
where studentresult < 60 and subjectid =(select subjectid from subject
where subjectname = 'JavaSE' ));练习:
-- 查询参加“JavaSE”课程最近一次考试的在读学生名单
-- 该需求涉及到 subject课程表 和 result成绩表 以及 student学生表
-- 其中subject表和result表之间采用 subjectid 字段关联
-- 其中result表 和 student表之间采用 studentno 字段关联
-- 先由课程名称得到课程编号,再由课程编号和最近一次考试时间得到学生编号
-- 最后由学生编号得到学生的名字
select studentname from student
where studentno = ( select studentno from result
where examdate = ( select max(examdate) from result
where subjectid = ( select subjectid from subject
where subjectname = 'JavaSE'))
and subjectid = ( select subjectid from subject
where subjectname = 'JavaSE'));
- 查询和Ben一个部门的员工的id,first_name,dept_id,salary信息
- -- 显示所有工资超过Ben的员工的信息,包括:id,first_name,salary
-- 显示工资高于全公司平均工资的员工信息,包括id,first_name,salary
-- 显示工资高于部门id=43的平均工资 的员工信息,包括id,first_name,salary
-- 显示所有工资等于 部门43的任意员工 的信息,包括id,first_name,salary
-- 返回管理者的信息,id,first_name,salary,也就是id号和manager_id相同
-- 显示所有工资大于 部门43的任意员工 的信息,包括id,first_name,salary
-- 显示平均工资 比部门id=33高的 部门id和平均工资
- create or replace view my_account_view as
select id,acc_no from xdl_bank_account_33;
- drop view my_account_view;
- create index 索引名 on 表名(字段名);
- drop index 索引名;
- create sequence 序列名;
- 调用序列的 nextval 或者 currval 使用currval必须调用nextval
select dept_id_seq.nextval from dual;
insert into dept values(dept_id_seq.nextval,'test'||dept_id_seq.currval,
'bj');
- create sequence 序列名 start with 值 minvalue 值;
create sequence emp_id_seq start with 100;
记住使用时 复杂序列 和 简单序列没有区别
- drop sequence 序列名;
- 1:1
表1(夫) 表2(妻)
maruzhong xiaoli
1 1
1 1
dengchao sunli
1 1
1 1
1:m
部门 员工
1 m
1 1
m:m
学生 课程
1 m
m 1
- 一对一
hid hname hbir wid wname wbir
1 mayun 1965 2 test 1990
2 mahuateng 1975 4 test2 1986
3 maruzhong 2001 6 test5 2015
hid hname hbir mid
1 mayun 1965 null
2 mahuateng 1975 2
3 maruzhong 2001 3
wid wname wbir mid
2 test 1990 1
4 test2 1986 3
6 test5 2015 2
4.2.2 一对多的设计
eid ename eage esalary did dname dcity
1 ea 20 8000 1 da bj
2 ea 21 12000 1 da bj
3 ec 22 20000 1 da bj
4 ed 25 35000 2 db nj
5 ee 30 50000 2 db nj
-
利用范式 进行拆表
eid ename eage esalary did
1 ea 20 8000 1
2 ea 21 12000 1
3 ec 22 20000 1
4 ed 25 35000 2
5 ee 30 50000 2did dname dcity
1 da bj
2 db nj
7.让下面的表 满足第三范式
id sid sname sage cid cname ctime cpoint
1 1 shq 33 1 java 100 80
2 1 shq 33 2 python 90 70
3 1 shq 33 3 php 80 60
4 2 zly 25 1 java 100 80
5 2 zly 25 2 python 90 70
学生选课关系表
id sid cid
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
课程表
cid cname ctime cpoint
1 java 100 80
2 python 90 70
3 php 80 60
学生表
sid sname sage
1 shq 33
2 zly 25
1.1 加载驱动
Class.forName("包名.驱动名")
1.2 获取连接 Connection
DriverManager.getConnection(url,username,password)
比如连接oracle 的url 是 jdbc:oracle:thin:@127.0.0.1:1521:xe
1.3 定义sql 并获取sql的执行环境 Statement (PrepareadStatement)
conn.createStatement() 这里以后会使用 prepareadStatement
1.4 执行sql 处理sql 返回值
select 返回ResultSet 遍历 st.executeQuery
dml 返回int 代表影响的数据行数 st.executeUpdate
1.5 释放资源
Connection Statement ResultSet
2.重新建立一个项目 导入oracle 的驱动包 然后按照上面的编写步骤 编写一个可以
根据账号 和 密码 来查询银行账户 如果有银行账户则输出登录成功 否则 输出登录失败。账号和密码
采用键盘输入。
3.使用PreparedStatement 替换 Statement
3.1 可以防止拼接的sql注入 原理就是你输入的数据不拼接 直接作为真实数据
3.2 由于采用预编译 会提前生成sql的执行计划 提高执行效率
3.3 拼接sql 每次sql是不同的 这会给数据库服务器的sql缓冲造成冲击 无法实现批处理
3.4 由于不拼接sql 程序员出错的概率会降低 提高编码质量和速度
4.使用PreparedStatement 完成从键盘录入银行账户的id值 完成根据id 删除银行账户
5.使用PreparedStatement 完成从键盘录入银行账户的信息 把银行账户的数据插入到
数据库中 注意 id 使用序列产生值。
- 工具类的思想
- 负责获取数据库的连接 以及资源的释放 提高代码复用度
- 配置文件的思想
- 可以不修改源代码的情况下 修改参数数据
- DAO
- 什么是DAO
- Data Access Object 数据访问对象
- 它是对数据访问过程 封装的对象
- 如何编写DAO
- 根据需求编写DAO 对应的接口
- 使用DBUtil 工具类 结合JDBC编程的五步 实现接口中对应的方法
- 练习
- 仿照根据id查询银行账户 完成 根据账号和密码查询银行账户
- 使用DAO 查询银行账户表中的所有数据
- 使用DAO 根据id 删除银行账户