數據庫技術(1)-SQL語句
(1)基本SQL語句
SQL語句分爲一下三種類型:
- DML:Data Manipulation Language:數據操縱語言
- 用於查詢與修改數據記錄
- INSERT
- UPDATE
- DELETE
- SELECT
- 用於查詢與修改數據記錄
- DDL:Data Definition Language 數據定義語言
- 用於定義數據庫的結構,比如創建,修改,或刪除對象
- CREATE TABLE
- ALTER TABLE
- DROP TABLE
- CREATE INDEX
- DROP INDEX
- 用於定義數據庫的結構,比如創建,修改,或刪除對象
- DCL:Data Control Language 數據控制語言
- 用來控制數據庫的訪問
基本SQL語句
- 查詢表中所有列
select * from employee;
- 查詢表中的特定列
select employee_id,lat_name,email from employees;
- 注:sql對大小寫不敏感
- 日期可以進行加減,但是不可以進行乘除運算
- 空值是無效的,未指定的,未知或不可預知的值
- 空值不是空格或者0
- 包含空值的數學表達式的值都爲空值
- 連接符
- 把列與列,列與字符連接起來
- 用 '||'表示,相當於連接符號+s
- 可以用來合成列
- eg.
- select last_name ||' `s job_id is '|job_id
- 查看錶結構
- desc [table_name]<=======sql plus的關鍵字
- 更改列名
- select employee_id id,last_name name,12*salary annual_sal from [table_name]
- select employee_id as id .... as可加可不加
- select employee_id as "id",last_name "Name",12*salary annual_sal from employee (當需要確定大小寫時一定需要加上引號)
- 去除重複行
- select distinct department_id from employees;
- sql語句
- 一種語言
- ANSI標準
- 關鍵字不能縮寫
- sql*plus命令
- 一種環境
- Oracle的特性之一
- 關鍵詞以縮寫
- 命令不能改變數據庫中數據的值
- 集中運行
(2) 過濾和排序數據
- 過濾
- eg1.
- select last_name,hire_date from employees where to_char(hire_datem'yyyy-mm-dd')='1994-06-07'
- 過濾條件
- between and(適合連續值):包含邊界
- in(適合離散值)
- select last_name,department_id,salary from employees
where department_id in(70,80,90)
- like查詢
- eg.員工中含有字符a的員工有哪些
- select last_name,department_id,salary from employees where last_name like '%a%'
- % 表示從0-無窮多個
- eg.員工中名字的第二位是a的員工有哪些
- select last_name,department_id,salary from employees where last_name like '_a%'
- eg.員工中名字的第三位是a的員工有哪些
- select last_name,department_id,salary from employees where last_name like '__a%'
- eg.查詢員工中的名字含有下劃線的人有哪些
- 假設有個員工爲'wgha_lanan'
- select last_name like '%#_%' escape '#'
- select last_name like '%\_%' escape '\'
- is null 與 is not null
- 排序 Order by
- select last_name,department_id,salary from employees
where department_id=80
order by salary asc(升序)
- select last_name,department_id,salary from employees
where department_id=80
order by salary asc,last_name asc
(3) 單行函數(dual對應一個虛表)
- 定義:
- 一行記錄對應好一個結果
- 字符函數
- 大小寫控制
- lower(‘ADFAD’) 小寫
- upper('ADAjj) 大寫
- initcap(‘sdsSDS’) 首字母大寫
- 字符控制函數:
- CONCAT 連接
- SUBSTR 取子串(下角標從1開始)
- LENGTH
- INSTR
- LPAD:左對齊:LPAD(SALARY,10,’’):左邊填不滿用補齊
- RPAD:右對齊
- TRIM:將一個字符從一個字符串去除,只可以去除首和尾
- REPLACE
- 大小寫控制
- 數字函數
- ROUND:四捨五入函數
- TRUNC:截斷函數
- MOD():取餘函數
- 日期函數
- 可以用數字除以24來向日期加上或減去天數
- MONTHS_BETWEEN:兩個日期相差的月數
- ADD_MONTHS:向制定日期中加上若干月數
- NEXT_DAY:指定日期的下一個星期’對應的日期’
- LAST_DAY:本月的最後一天
- ROUND:日期四捨五入
- TRUNC:日期截斷
- 轉換函數
- 數據類型轉換
- 隱式
- date<---->varchar2<----->number
- 顯示
- 字符與日期(char–date):
- where hire_date=‘7-6月-94’
- where to_char(‘hire_date’,‘yyyy-mm-dd’)=‘1997-06-07’
- where to_date(‘1997-06-07’,‘yyyy-mm-dd’)=hire_date
- 字符與數字
- to_number
- to_char
- 字符與日期(char–date):
- 隱式
- 數據類型轉換
- 通用函數
- NVL:將空值轉換成一個已知的值
- NVL2(expr1,expr2,expr3)
- NULLIF(expr1,expr2):相等返回NULL,不等返回expr1
- 字符函數
- 條件表達式
- case表達式
- 一行記錄對應好一個結果
select last_name "last_name",job_id "job_id" when 'AD_PERS' then 'A'
when 'ST_MAN' then 'B'
when 'IT_PROG' then 'C'
when 'SA_REP' then 'D'
when 'ST_CLERK' then 'E' end "Grade"
from employees
- decode表達式
select last_name,job_id,decode(job_id,'AD_PERS','A',
'ST_MAN','B',
'IT_PROG','C',
'SA_REP','D',
'ST_CLERK','E') "Grade"
from employees
(4)多表查詢
- 等值連接
查詢出公司員工的last_name,department_name,city:
select last_name,department_name,city
from department d,employees e,location l
where d.department_id=e.department_id and d.location_id=l.location_id;
查詢出last_name 爲'Chen'的manager的信息 (員工的employee_id等於員工的manager_id)
0) 例如:老張的員工號爲:"1001",我的員工號爲:"1002"
我的manager_id爲 "1001"-----我的manager是"老張"
1) 通過兩條sql語句進行查詢
select manager_id
from employees
where lower(last_name)='chen' --- 返回的結果爲108
select *
from employees
where employee_id=108
2) 同過一條sql查詢(自連接)
select m.*
from employees e,employees m
where e.manager_id=m.employee_id and e.last_name='Chen'
3) 通過一條sql查詢(子查詢)
select *
from employees
where employee_id=(
select manager_id
from employees
where last_name='Chen'
)
- 非等值連接
查詢每個員工的last_name 和 GRADE_LEVEL (在JOB_GRADES 表中)-----非等值連接
select last_name,GRADE_LEVEL
from employees e,job_grades j
where e.salary>=j.lowest_sal and e.salary<=j.hightest_sal
- 外連接
- 左外連接
select last_name,e.department_id,department_name
from employee e,department d
where e.department_id=d.department_id(+)
- 右外連接
select last_name.e.department_id,department_name
from employee e,department d
where e.department(+)=d.departemnt_id
理解(+)的位置: 以左外連爲例,因爲在左表需要返回更多的記錄,右表就需要加上更多的
記錄,因此在右表的鏈接條件上加上"(+)"
- sql 99 的左外連接,右外連接,滿外連接
1) 左外連接
select last_name,department_name
from employees e left join departments d
on e.department_id=d.department_id
2) 右外連接
select last_name,department_name
from employees e right join in departments d
on e.departemnt_id=d.department_id
3) 滿外連接
select last_name,departemnt_name
from employees e full join in departemnnts d
on e.departemnt_id=d.departemnt_id
- sql 99 中連接 Employees 和 Departement表
1) 缺點:要求兩個表中的必須擁有一樣會的別名
select *
from employees join departments
using(department_id)
2)
select *
from employees e join departments d
on e.department_id=d.department_id
3) 多表連接
select e.last_name,d.departemnt_name,l.city
from employees e join departments
on e.department_id=d.department_id
join locations l
on d.location_id=l.location_id
(5) 分組函數
-
分組函數作用於一組數據,並對一組數據返回一個值
-
不能在WHERE子句中使用組函數
-
可以在HAVING子句中使用組函數
-
組函數類型
- AVG
- 只能存放number類型
- COUNT
- 返回記錄中的總數
- 只記錄非空記錄
- AVG實際是由SUM/COUNT 而來,因此其計算時也忽略的空值
- 可使用NVL函數使分組函數無法忽略空值
- MAX
- MIN
- STDDEV
- SUM
- 只能存放number類型
- AVG
組函數應用:
select AVG(SALARY) MAX(SALARY) MIN(SALARY) SUM(SALARY)
from employees;
NVL函數使分組隱函數無法忽略空值:
select AVG(NVL(commission_pot,0))
from employees;
COUNT(DISTINCE expr) 返回expr非空且不重複的記錄總數
select COUNT(DISTINCT department_id)
from employees;
求出EMPLOYEES表中各部門的平均工資(按照不同部門進行分組)
select department_id,AVG(salary)
from employees
where department_id in(40,60,80)
group by department_id
在SELECT 列表中所有未包含在組函數中的列都應該包含在GROUP BY子句中
HAVING:
select department_id,avg(salary)
from employees
having avg(salary)>6000
group by department_id
order by department_id asc
嵌套組函數
select max(avg(salary))
from employees
查詢公司在1995-1998之間,每年僱傭的人數的格式
select count(*) "total"
count(decode(to_char(hire_date,'yyyy').'1995',1,null)) "1995"
count(decode(to_char(hire_date,'yyyy').'1996',1,null)) "1996" count(decode(to_char(hire_date,'yyyy').'1997',1,null)) "1997" count(decode(to_char(hire_date,'yyyy').'1998',1,null)) "1998"
from employees
where to_char(hire_date,'yyyy') in (1995,1996,1997,1998)
(6) 子查詢
- 單行子查詢
- 多行子查詢
- IN: 等於列表中的任意一個
- ANY: 和子查詢返回的某一個值進行比較
- ALL: 和子查詢返回的所有值進行比較
--- 誰的工資比Abel高?
select last_name,salary
from employees
where salary>( select salary
from employees
where last_name='Abel')
--- 查詢員工名爲Chen的manager的信息
select last_name,salary
from employees
where employee_id=( select manager_id
from employees
where last_name='Chen')
--- 查詢平均工資最高的job信息
7.創建和管理表(DDL)
-
常見的數據庫對象:
- 表:基本的數據存儲集合,由行和列組成
- 視圖:從表中抽出的邏輯上相關的數據集合
- 序列: 提供有規律的數值
- 索引: 提高查詢的效率
- 同義詞: 給對象起別名 -
表名和列名:
- 必須以字母開頭
- 必須在1-30個字符之間
- 必須只能包含A-Z,a-z,0-9,_,$,和#
- 必須不能和用戶定義的其他對象重名
- 必須不能是Oracle的保留字
-
數據類型:
- VARCHAR2(size) 可變長字符數據
- CHAR(size) 定長字符數據
- NUMBER(p,s) 可變長數值數據
- DATE:日期型數據
- LONG:可變長字符數據,最大可達到2G
- CLOB:字符數據,最大可達到4G
- RAW(LONG RAW):原始的二進制數據
- BLOB:二進制數據,最大可達到4G
- BFILE: 存儲外部文件的二進制數據最大可達到4G
- ROWID: 行地址
- 語句(以下DDL命令,操作之後皆不可回滾)
- 創建表: create table
- 修改表結構: alter table
- 刪除表: drop table
- 重命名錶: rename to
- 刪除表中的所有數據,並釋放存儲空間: truncate table
Oracle數據庫中的表:
1.查看用戶創建的表:
select * from user_tables;
2.創建表的第一種方式(白手起家):
create table emp1(
id number(10),
name varchar2(20),
salary number(10,2), //整個10位,小數位2位
hire_date date
)
3.顯示錶結構
desc emp1
4.創建表的第二種方式(依託於現有的表):
create table emp2
as
select employee_id id,last_name name,hire_date,salary
from employees
5. 修改表*(修改數據類型必須是空表):
alter table emp1
add(email varchar2(20))
alter table emp1
modify(id number(15))
6.刪除表
drop tabel emp5;
7.清空表(只是清除表中的數據)
truncate table emp3(不能回滾)
8.改名
rename emp2 to employees2;
8.數據處理
創建空表
create table emp1
as
select employee_id,last_name,hire_date,salary from employees
where 1=2
插入一條數據(數據格式一一對應)
insert into emp1
values(1001,'AA',sysdate,10000)
insert into emp1
values(1002,'BB',tochar('1998-12-21','yyyy-mm-dd'),20000)
insert into emp1
values(1003,'CC',to_date('1999-12-21','yyyy-mm-dd'),null)
插入不足值的數據 要求類型與數據一一對應
insert into emp1(employee_id,last_name,hire_date)
values(1004,'DD',to_date('1999-12-21','yyyy-mm-dd'))
從其他表中拷貝數據:
insert into emp1(employee_id,hire_date,last_name,salary)
select employee_id,hire_date,last_name,salary
from employees
創建腳本:
insert into emp1(employee_id,,last_name,salry,hire_date)
values(&id,'&name',&salary,'&hire_date')
更改數據 UPDATE
update emp1
set salary=12000
where employee_id=179
提交
commit;
刪除數據:DELETE語句
從employees1表中刪除dept1部門名稱中含pubic字符的部門id
delete from employees1
where department_id=(
select department_id
from depaetments
where department_name like='Public'
)
- 數據庫事務
- 事務:一組邏輯操作單元,使數據從一種狀態變換到另一種狀態
- commit:提交相當於保存
- rollback:
- savepoint A;
- rollback to savepoint A;
- 提交或回滾前的操作
- 其他用戶不能看到用戶所做的改變,直到當前用戶結束事務
- DML語句所涉及到的行被鎖定,其他用戶不能操作
- 提交後的數據狀態
- 鎖被釋放,其他用戶可以操作涉及到的數據
- sql優化
9.約束
- 什麼是約束:
- 約束是表級的強制規定
- 常見的約束:
- NOT NULL
- UNIQUE
- PRIMARY KEY:主鍵
- 不能加上空值
- 主鍵唯一
- FOREIGN KEY:外鍵
- CHECK
- 創建和修改約束
- 建表的同時
- 建表之後
- 表級約束和列級約束
- 列級約束只能作用在一個列上
- 表級約束:可以作用在多個列上
- 添加約束的語法:
- 添加或刪除約束,但不能修改約束
- 有效化或無效化約束
- 添加 NOT NULL 約束要使用 modify語句
創建表:
create table emp2(
id number(10) contraint emp2_id_nn not null, // 顯示聲明約束
name varchar2(20) not null,
salary(10,2)
)
顯示錶:
desc emp2
創建表
create table emp3(
---列級約束
id number(10) contraint_emp3_id_uk unique,
name varchar2(20) contraint emp3_name_nn not null,
email varchar(20),
salary number(10,2),
---表級約束
contraint emp3_email_uk unqiue(email)
)
創建表
create table emp4(
---列級約束
id number(10) contraint_emp4_id_pk primary key,
name varchar2(20) contraint emp4_name_nn not null,
email varchar(20),
salary number(10,2),
---表級約束
contraint emp3_email_uk unqiue(email)
contraint emp6_id_fk foreign key(department_id) references departments(department_id)
)
10.視圖:view
- 視圖
- 視圖是一種虛表
- 視圖建立在已有表的基礎上,視圖賴以建立的這些表稱爲基表
- 爲什麼要使用視圖:
- 控制數據訪問
- 簡化查詢
- 避免重複訪問相同的數據
- 簡單視圖和複雜視圖
- 沒使用分組函數的爲簡單視圖
- 使用分組函數的爲簡單的視圖
- Top-N 分析:
- 傳最大的幾個值的Top-N分析
- 對ROW_NUM只能使用小於等於
- row_num:表示僞列,數據本身沒有這樣的列,是Oracle數據庫爲每個數據表加上的列可以標識行號,默認情況下,rownum按主索引進行排序,沒有則自然排序
1.創建視圖
create view empview
as
select employee_id,last_name,salary
from employees
where department_id=80
2.視圖修改
3.視圖中刪除
delete from empview
where employee_id=176
4.基於多個表創建視圖
create view empview2
as
select employee_id,id,last_name,name,department_name
from employee e,department d
where e.department_id=d.department_id
5.修改視圖
使用 create or replace view子句修改視圖
6.屏蔽DML操作,可以使用with read only 選項屏蔽對視圖的DML的操作
with read only
7.刪除視圖
drop view [view_names];
8.top-n分析:
查詢工資排名前10的工資:
select rownum,employee_id,last_name,salary
from(
select rownum,employee_id,last_name,salary
from employees
order by salary desc
)
where rownum<=10
查詢40-50
select rn,employee_id,last_name,salary
from(
select rownum rn,employee_id,last_name,salary
from(
select employee_id,last_name,salary
from employees
order by salary desc
)
)
where rn>40 and rn<=50
9.對Orac對象le進行分列
select employee_id,last_name,salary
from(
select rownum rn,employee_id,last_name,salary
from employees
) e
where e.rn<=pageNo*pageSize and e.rn>(pageNo-1)*pageSize
11.其他數據庫對象
-
序列
- 可以多個用戶來產生唯一數值的數據庫對象
- 自動提供唯一的數值
- 共享對象
- 主要用於提供主鍵值
- 將序列值裝入內存中可以提高訪問效率
-
修改序列的注意事項:
- 必須是序列的擁有者,或者對序列有ALTER權限
- 只有將來的序列值會被改變
- 改變序列的初始值只能通過刪除序列之後重建序列的方法實現
-
使用序列:會出現"裂縫"現象
-
索引
- 一種獨立於表中的模式對象,可以存儲在與表不同的磁盤或表空間中
-
創建索引
- 自動索引
- 手動創建索引
-
什麼時候創建索引
- 列中數據值分佈範圍很廣
-
什麼時候不要創建索引:
- 表很小
-
同義詞
1.創建一個序列:
create sequence empseq
increment by 10 --每次增長10
start with 10 --從10開始增長
maxvalue 100 --提供的最大值
cycle --需要循環
nocache --不需要緩存
2.// 首次必須先進行nextval
select empseq.curval from dual
select empseq.nextval from dual
// 序列的使用
create table emp01
as
select employee_id,last_name,salary
from employees
where 1=2
3.// 修改序列
alter sequence empseq
increment by 12
nocycle
4.創建索引
create index emp01_id_ix
on emp01(employee_id)
5.刪除索引
6.創建同義詞
CREATE SYNONYM e FOR employees
12.控制用戶權限
數據庫安全性:
- 系統安全性
- 數據安全性
系統權限:對於數據庫的權限
- 有一百多種權限
- 數據庫管理員具有高級權限以完成管理任務
對象權限:操作數據庫對象的權限
1.創建用戶
create user xiaoyao
identified by xiaoyao
2.用戶的系統權限-創建會話
grant create session
to xiaoyao
grant create table
to xiaoyao
3.創建用戶表空間
alter user xioayao quota unlimted(5m)
on users;
4.更改用戶賬戶密碼
alter user xiaoyao
identified by xiaoyaotest
5.創建角色
create role my_role;
6.賦予角色權限
grant create session,create_tabe,create view to my_role
create user xiaoyao02
grant my_role to xiaoyao02
7.對象權限
grant select,update
on scott.employees
to xiaoyao
8.with grant options:表示可以可別人授予權限
public 關鍵字:表示給所有用戶權限
9.revoke 語句表示收回已授予的權限
13.SET操作符
- UNION/UNION ALL: 求並集
- 默認按照第一列順序排序
- INTERSECT: 求交集
- MINUS: 求差集
列數必須對應相同 實現兩個表的並集
select emplyee_id,department_id
from employees01
union all
select employee_id,department_id
from employee02
14.高級子查詢
1.多列子查詢
開始實現:
select employee_id,manager_id,department_id
from employees e1
where manager_id in (
select manager_id
from employees
where employee_id in (141,174)
) and department_id in (
select department_id
from employees
where employee_id in (141,174)
)
and empoyee_id not in(141,174)
多列子查詢:
select employee_id,manager_id,department_id
from employees e1
where (manager_id,department_id) in (
select (manager_id,department_id)
from employees
where employee_id in (141,174)
)
and employee_id not in (141,174)
2.在FROM 子句中使用子查詢
select last_name,department_id,salary
from employees e1
where salary> (
select avg(salary)
from employees e2
where e1.department_id=e2.department_id
group department_id
)
3. 相關子查詢:按照一行接一行的順序只能執行,主查詢的每一行都執行一次子查詢
select last_name,salary,department_id
from employees outer
where salary>(
select avg(salary)
from employees
where department_id=outer.department_id
)
4.EXISTS 操作符
- 檢查在子查詢中是否存在滿足條件的行
5. NOT EXISTS 操作符
6.with子句