學習筆記day64-----oracle-sql標準的表連線、集合運算、函式和分組、子查詢、表操作
阿新 • • 發佈:2019-01-29
1、sql標準中的表連線
1.1、內連線
語法:
select 欄位列表
from 表1 [inner] join 表2
on 關聯條件;
--三表
select 欄位列表
from 表1 join 表2 on 關聯條件1
join 表3 on 關聯條件2;
select e.id,e.first_name,d.name dname,r.name rname from s_emp e join s_dept d on e.dept_id=d.id join s_region r on d.region_id=r.id;
1.2、外連線
左外連線:內連線的結果集加上左表匹配不上的資料
select 欄位連結串列
from 左表 left outer join 右表
on 關聯條件;
右外連線:內連線的結果集加上右表匹配不上的資料
select 欄位列表
from 左表 right [outer] join 右表
on 關聯條件;
全外連線:內連線的結果集加上兩表匹配不上的資料
select 欄位列表
from 左表 full [outer] join 右表
on 關聯條件;
--內連線
select e.id,e.first_name,d.name from s_emp e join s_dept d on e.dept_id=d.id;
--左外連線
select e.id,e.first_name,d.name from s_emp e left join s_dept d on e.dept_id=d.id;
--右外連線
select e.id,e.first_name,d.name from s_emp e right join s_dept d on e.dept_id=d.id;
--全外連線
select e.id,e.first_name,d.name from s_emp e full join s_dept d on e.dept_id=d.id;
select e.id,e.first_name,d.name from s_emp e full join s_dept d on e.dept_id=d.id where e.id is null;
2、集合運算
union :返回兩個結果集的並集,去掉重複行
union all:返回兩個結果集的並集,不去重複行
select id from s_emp union select id from s_dept;
select id from s_emp union all select id from s_dept;
intersect:返回兩個結果集中相同的部分
select id from s_emp intersect select id from s_dept;
minus:返回第一個結果集減去兩個結果集的交集之後的部分
select id from s_emp minus select id from s_dept;
注意:兩個結果集的欄位列表的數量和資料型別要匹配
還可以用null來填充
select first_name,id from s_emp union select null,id from s_dept;
3、組函式和分組
3.1、常用的組函式
3.1.1、功能
count 統計一組資料的個數
select count(salary) from s_emp;
引數可以是任意型別 可以使用*
max 統計一組資料的最大值
min 統計一組資料的最小值
select max(salary),min(salary) from s_emp;
select to_char(max(start_date),'yyyy-mm-dd'),to_char(min(start_date),'yyyy-mm-dd') from s_emp;
引數可以是數值、數值、日期字串
sum 統計一組資料的和
avg 統計一組資料的平均值
select sum(salary),avg(salary) from s_emp;
3.1.2、組函式對NULL的處理--忽略
select count(manager_id) from s_emp;
3.1.3、引數可以使用distinct
select count(salary),count(distinct salary) from s_emp;
select sum(salary),sum(distinct salary) from s_emp;
3.2、分組
3.2.1、分組語句的語法
多列分組
根據分組標準,把資料分成多個部分
group by 分組標準
select
from
where
group by
order by
3.2.2、按照部門分組,統計每個部門的人數
select dept_id,count(id) cnt from s_emp e group by dept_id;
--在分組語句中,欄位要麼是分組標準,要麼是組函式的引數
--列出每個部門的編號、名稱以及人數
select e.dept_id,d.name dname,count(e.id) from s_emp e join s_dept d on e.dept_id=d.id group by e.dept_id,d.name;
--列出部門人數多餘2人的部門
錯誤的,主函式不能在where子句中使用
select e.dept_id,d.name dname,count(e.id) from s_emp e join s_dept d on e.dept_id=d.id where count(id)>2 group by e.dept_id,d.name;
3.2.4、having子句
語法:
having 條件
功能:在分組語句中,根據條件篩選符合條件的組
select dept_id,count(id) cnt from s_emp where 1=1 group by dept_id having count(id)>2 order by cnt desc;
語法順序:
select 列出要顯示的欄位列表
from 從哪個表中檢索資料
where 從元表中根據條件篩選符合條件的行
group by 根據分組標準,把資料分成多個部分
having 根據條件,對分組結果進行篩選,檢索出符合分組條件的部分
order by 根據排序標準對結果集進行排序
執行順序:
from 從哪個表中檢索資料
where 從元表中根據條件篩選符合條件的行
group by 根據分組標準,把資料分成多個部分
having 根據條件,對分組結果進行篩選,檢索出符合分組條件的部分
select 列出要顯示的欄位列表
order by 根據排序標準對結果集進行排序
--統計每個部門的平均工資,累出平均工資超過1400的部門資訊
select d.id,d.name,avg(salary) avgs from s_emp e join s_dept d on e.dept_id=d.id group by d.id,d.name having avg(salary)>1400 order by avgs desc;
4、子查詢
子查詢就是一個select語句嵌入到另一條sql語句中,作為其中的一部分。
其中,嵌入的select語句,稱為子查詢;外層的sql語句,稱為父查詢
在執行時,先執行嵌入的子查詢,再執行父查詢。
4.1 where子句中
4.1.1、單值的子查詢
where子句中的條件 可以使用比較運算子(<>等)
--列出工資高於‘Ben’的員工的資訊
select id,first_name,salary from s_emp where salary>(select salary from s_emp where first_name='Ben');
4.1.2、多行單列的子查詢
當子查詢的結果是多行單列時,需要使用能夠處理多隻的運算子,比如in、not in、any、all等。
any、all需要和比較運算子配合使用,比如>any、<all等
--使用子查詢,列出s_emp表中的領導的資訊
select id,first_name from s_emp where id in(select distinct manager_id from s_emp);
--列出所有普通員工的資訊
select id,first_name from s_emp where id not in(select distinct nvl(manager_id,0) from s_emp);
注意:在not in中不能帶有null值,
原理:
in(null,1,2)==> x=null or x=1 or x=2
not in(null,1,2)==> x!=null and x!=1 and x!2 ==>永遠為假
4.1.3、子查詢中需要引用父查詢中的欄位,使用exists關鍵字
--列出有員工的部門
select d.id,d.name from s_dept d where exists (select * from s_emp e where e.dept_id=d.id);
4.2、having子句
--列出平均工資高於43號部門平均工資高的部門資訊
select dept_id,avg(salary) avgs from s_emp group by dept_id having avg(salary)>(select avg(salary) from s_emp where dept_id=42);
4.3、from子句中
任何一個合法的select語句,都會在記憶體中構建一張臨時表,可以稱為記憶體表
--列出工資高於公司的平均工資的員工資訊
select id,first_name,salary from s_emp where salary>(select avg(salary) from s_emp);
--列出工資高於本部門平均工資的員工
select e.id,e.first_name,e.salary,s.avgsa from s_emp e, (select dept_id did,avg(salary) avgsa from s_emp group by dept_id) s
where e.dept_id=s.did and e.salary>s.avgsa;
4.4、select子句中
把子查詢放到select子句中,可以認為是外連線的另一種實現方式
--列出所有員工的編號名字和所在部門的名稱
select e.id,e.first_name,(select name from s_dept d where e.dept_id=d.id) dname from s_emp e;
5、表操作
5.1、識別符號的命名
1) 首字母必須是英文字母
2) 包含因為字母、數字、'_'、$、#
3) 1~30未完、
4) 不能和其他的資料庫物件重名
5) 不能是使用關鍵字
5.2、建立表和刪除表
1) 語法:
create table 表名(
欄位名 資料型別,
欄位名 資料型別,
...
欄位名 資料型別。
);
2) 示例
create table emp_lx_42( id number(7), name varchar2(20), salary number(11,2), s_date date);
5.2.2、刪除表
語法:
drop table 表名
--刪除emp_lx_42
drop table emp_lx_42;
select table_name from user_tables where table_name like 'EMP%';
5.3
5.3.1、insert語句
功能:向表中寫入資料行
1)語法
insert into 表名[(欄位列表)] values(值列表);
2)示例
insert into emp_lx_42(id,name,salary,s_Date) values(1,'test1',2500,to_date('2018-07-06','yyyy-mm-dd'));
提交
commit;
insert into emp_lx_42 values(2,'test2',2000,to_date('2018-07-05','yyyy-mm-dd'));
insert into emp_lx_42(id,name,s_date) values(3,'test3',sysdate);
5.3.2、update語句
功能:根據條件更改表中的資料
語法:
update 表名 set 欄位=新值[,欄位=新值,...] [where 子句];
--修改員工的工資,每人加1000,3000封頂
update emp_lx_42 set salary = 3000 where salary > 2000;
update emp_lx_42 set salary = salary + 1000 where salary <= 2000;
--把salary為null的員工的salary設定為2500
update emp_lx_42 set salary = 2500 where id = 3;
回滾
rollback;
update emp_lx_42 set name='Ben',salary=2500,s_date='01-JUL-18' where id=1;
5.3.3、delete語句
功能:根據條件刪除表中的資料行
語法:
delete [from] 表名 [where 子句];
示例:
delete from emp_lx_42;
delete from emp_lx_42 where id = 3;
--截斷表
truncate table 表名;--屬於ddl語句
功能:相當於沒有where子句的delete語句,而且不能回滾