SQL總結(jié)

目錄

簡介

在Android中存儲(chǔ)數(shù)據(jù)有時(shí)會(huì)用到數(shù)據(jù)庫,Android給我們提供了 一系列的API來操作數(shù)據(jù)庫,非常簡單,我們只需要輸入對(duì)應(yīng)的SQL語句,甚至不懂SQL語句,只傳入對(duì)應(yīng)的參數(shù)即可使用。還有一些第三方庫,如GreenDao,OrmLite等都極大的簡化了對(duì)數(shù)據(jù)庫的一些操作。這樣雖然我們不需要對(duì)數(shù)據(jù)庫有多了解一樣能實(shí)現(xiàn)功能,但是在面對(duì)復(fù)雜操作時(shí),對(duì)SQL語句的熟練使用就顯得尤為重要了。因?yàn)樵贏ndroid我們只要是利用SQL語句對(duì)表操作,所以本文主要介紹SQL的使用,只是簡單介紹了數(shù)據(jù)庫一些相關(guān)的概念,這樣能有更加清晰的認(rèn)識(shí)。

數(shù)據(jù)模型

按照計(jì)算機(jī)系統(tǒng)的觀點(diǎn)對(duì)數(shù)據(jù)進(jìn)行建模。

概念模型

也稱為信息模型,即按照用戶的觀點(diǎn)來對(duì)數(shù)據(jù)和信息建模

  • 實(shí)體(Entity):客觀存在并可互相進(jìn)行區(qū)分的事物稱為實(shí)體
  • 屬性(Attribute):實(shí)體所具有的某一特性稱為屬性,一個(gè)實(shí)體可有若干個(gè)屬性來刻畫。
  • 鍵(KEY):唯一標(biāo)識(shí)實(shí)體的屬性集稱為鍵,一般分為超鍵、候選鍵、主鍵以及外鍵。
  • 域(Domain):屬性的取值范圍稱為該屬性的域。
  • 實(shí)體型(Entity type):用實(shí)體名以及其屬性名集合來抽象和刻畫同類實(shí)體稱為實(shí)體型
  • 實(shí)體集:同型實(shí)體的集合稱為實(shí)體集

現(xiàn)實(shí)世界的實(shí)體進(jìn)入數(shù)據(jù)庫

  • 1.講現(xiàn)實(shí)世界中的客觀對(duì)象抽象為概念模型
  • 2.把概念模型轉(zhuǎn)化為某一DBMS(數(shù)據(jù)庫管理系統(tǒng))支持的數(shù)據(jù)模型

鍵的概念

  • 超鍵(super key):在關(guān)系中能唯一區(qū)分實(shí)體的屬性集稱為關(guān)系模式中的超鍵。
  • 候選鍵(candidate key):不含有多余屬性的超鍵(每一個(gè)屬性都能區(qū)分實(shí)體)
  • 主鍵(primary key):用戶選作區(qū)分實(shí)體發(fā)的一個(gè)候選鍵(foreign key)
  • 外鍵:在某個(gè)關(guān)系A(chǔ)中的主鍵出現(xiàn)在另一個(gè)關(guān)系B中,此時(shí)關(guān)系A(chǔ)中的該主鍵稱為關(guān)系B中的外鍵。

例子說明: 員工(身份證號(hào)、姓名、年齡、性別)假設(shè)姓名也是唯一的超鍵:身份證號(hào)、姓名、姓名+年齡、姓名+性別、身份證號(hào)+年齡、身份證號(hào)+性別候選鍵:身份證號(hào)、姓名

數(shù)據(jù)庫設(shè)計(jì)范式

數(shù)據(jù)庫設(shè)計(jì)范式簡單的說就是關(guān)系數(shù)據(jù)庫在設(shè)計(jì)時(shí)需要遵循的一種規(guī)范,數(shù)據(jù)庫范式按照要求從低到高分為6大范式,即第一范式(1NF)~第六范式(6NF)。在第一范式的基礎(chǔ)上進(jìn)一步滿足更多要求的稱為第二范式,一次類推。越高的范式數(shù)據(jù)庫冗余越小,一般來說,數(shù)據(jù)庫只需要滿足第三范式(3NF)就行了。

第一范式

是數(shù)據(jù)庫設(shè)計(jì)的最基本的要求,不滿足1NF的數(shù)據(jù)庫不是關(guān)系型數(shù)據(jù)庫
所謂第一范式就是指數(shù)據(jù)庫表的每一列都是不可分割的基本數(shù)據(jù)項(xiàng),同一列中只能有一個(gè)屬性(也就是說一個(gè)屬性下不能再分出其他的屬性來)

第二范式

第二范式是在第一范式的基礎(chǔ)上建立起來的,即滿足2NF必須先滿足1NF
只出現(xiàn)在復(fù)合主鍵的數(shù)據(jù)庫表中
第二范式要求數(shù)據(jù)庫表中的每個(gè)實(shí)例或者行必須可以被唯一地區(qū)分,所以實(shí)體必須設(shè)置主鍵,并且實(shí)體的屬性必須完全依賴于主鍵,不得出現(xiàn)非主鍵屬性部分依賴于主鍵的情況。

主鍵為學(xué)號(hào)+課程名稱,而學(xué)分依賴于學(xué)號(hào),這就是所謂的非主鍵屬性依賴于主鍵的情況,這是不符合2NF的,出現(xiàn)了數(shù)據(jù)的冗余(存儲(chǔ)多余的數(shù)據(jù),浪費(fèi)空間),解決辦法就是拆成3張表。

第三范式

要求一個(gè)數(shù)據(jù)庫表中不包含已在其他表中已包含的非主關(guān)鍵字信息(非主鍵屬性不能出現(xiàn)在第二張表中)

非主鍵屬性重復(fù)了,完全可以根據(jù)編號(hào)(主鍵)去查詢部門簡介和名稱

數(shù)據(jù)庫設(shè)計(jì)的完整性約束

實(shí)體完整性約束

每個(gè)實(shí)例或者行的主鍵都不能為空

參照完整性約束

外鍵可以為空值;當(dāng)外鍵不為空時(shí),其取值只能等于參照的主鍵的某個(gè)值

數(shù)據(jù)庫的約束

約束是表級(jí)強(qiáng)制執(zhí)行的規(guī)則,當(dāng)表中數(shù)據(jù)有相互依賴性時(shí),可以保護(hù)數(shù)據(jù)不被刪除

約束的類型:

  • 表級(jí)約束和列級(jí)約束,他們兩者在作用上沒有任何的區(qū)別,但通常如果某個(gè)約束用于于不止一個(gè)列時(shí),只能使用表級(jí)約束的形式來進(jìn)行表達(dá),如果多個(gè)字段組成耨表的聯(lián)合主鍵時(shí)。
  • 列級(jí)約束: 在定義列的時(shí)候:列名 約束類型 表級(jí)約束 在定義完所有的列后:列名,列名,。。。 約束類型

oracle有如下類型的約束:

not null:非空
primary key:主鍵約束
foreign key:外鍵約束
check:檢查約束
unique key:唯一性約束

not null(非空約束)

create table student(
     name varchar2(10), 
     sex varchar(5) not null, 
     age integer)

primary key(主鍵約束)

表級(jí)方式定義主鍵

create table student( 
    name varchar2(19),
    sex varchar2(10),
    age integer,
    constraint student_age_pk primary key(age)
    );

把a(bǔ)ge定義為主鍵(student_age_pk:約束的名字有一定的規(guī)范:表名主鍵名約束類型)

列級(jí)方式定義主鍵

create table student( 
   name varchar2(19) primary key,
   sex varchar2(10),
   age integer);

foreign key(外鍵約束)

create table emp(
   empno number(4), 
   ename varchar2(10) not null, 
   job varchar2(9),
   deptno number(7,2) not null, 
   constraint emp_deptno_fk foreign key(deptno) references dept (deptn)
   );

--references dept (dept):外鍵所對(duì)應(yīng)的主鍵所在的表 關(guān)鍵字 主表 主鍵

SQL語句

  • 常用數(shù)據(jù)類型 2.子查詢(單行子查詢和多行子查詢)
  • select語句 條件查詢 模糊查詢 簡單去掉重復(fù)的查詢結(jié)果 關(guān)于空值
  • order by
  • 單行函數(shù)
  • 字符函數(shù)
  • 數(shù)值處理函數(shù)
  • 日期處理函數(shù)
  • 類型轉(zhuǎn)換函數(shù)
  • 通用函數(shù)
  • 組(聚合)函數(shù)
  • 語句的執(zhí)行順序
  • insert
  • detect
  • update
  • 事務(wù)與鎖
  • DDL語句(數(shù)據(jù)定義語言)
  • 多表聯(lián)合查詢
  • 集合
  • 視圖
  • 約束條件
  • 添加注釋
  • 索引
  • 經(jīng)典案例

常用數(shù)據(jù)類型

  • varchar2(size):可變長度的字符串,最大長度為size個(gè)字節(jié),size最大值為4000,最小值為1
  • char(size):固定長度的字符數(shù)據(jù),其長度為size個(gè)字節(jié),最大值為2000,最小值和默認(rèn)值為1,不管實(shí)際的長度為多少都會(huì)分配指定的size個(gè)字節(jié)
  • number(p,s):有效位數(shù)為p且精度為s的數(shù)值(小數(shù)點(diǎn)后有s位)p的取值范圍為1到38
  • date:有效日期范圍從公元前4712年1月到公元后4712年12月31日
  • long:可變長度的字符數(shù)據(jù),其長度可達(dá)2G個(gè)字節(jié)

查詢

子查詢

  • 子查詢?cè)谥鞑樵兊那耙淮螆?zhí)行
  • 主查詢使用子查詢的結(jié)果
  • 子查詢要用括號(hào)括起來
  • 將子查詢放在比較運(yùn)算符的右邊
  • 子查詢中不要加ORDER BY子句

應(yīng)用場(chǎng)景:例如那些雇員的工資比林志玲的高?

單行子查詢

  • 查詢結(jié)果為一行

  • 單行子查詢只能使用單行比較運(yùn)算符 =,>,>=,<,<=,<>

    select name,job from emp where job = (select job from emp where empno = 7369);
    select ename,job,sal from emp where sal=(select min(sal) from emp)
    

相關(guān)子查詢

多行子查詢

  • 查詢結(jié)果為多行
  • 多行子查詢只能使用多行比較運(yùn)算符

    IN:等于列表中的任何值
    ANY:比較子查詢返回的每一個(gè)值,只要其中一個(gè)滿足條件就返回true
    ALL:比較子查詢返回的每一個(gè)值,要其中所有的值都滿足條件才返回true

使用IN:

select empno,ename,job from emp where deptno in(select deptno from emp where ename = 'SMITH' or ename ='MITLER');

使用ANY

  • <ANY : 指小于最大值

  • ANY : 指大于最小值

  • ANY:與IN等價(jià)

    select empno,ename,job from emp where sal <ANY (select sal from emp where job = 'clerk')
    

使用ALL

  • <ALL : 指小于最小值
  • ">ALL" : 指大于最大值
select empno,ename,job,sal from emp where sal > ALL(select avg(sal) from emp GROUP BY depton)

SQL語句

  • select語句

select 列名 form 表名select name from student
select * from student :查詢所有的列
select name,sex from student

  • select name as myname from student:隊(duì)列中使用別名

    • 查詢結(jié)果顯示的列用別名顯示(as 用別名顯示)
    • 之前是結(jié)果列名為name as后為myname
    • 不寫as就要加引號(hào)或者空格:select name "myname" form student
  • 列使用算數(shù)表達(dá)式:

    • select name,sal,sal+100 from student: 查詢sal和sal+100
  • 關(guān)于空值

    • 空值為不可用,不知道,不適用的值
    • 空值不等于0或者空格
    • 包含空值的算數(shù)表達(dá)式等于空
  • 連接操作符

    • 可將列或者字符與其他列連接起來,用雙豎線標(biāo)識(shí)(||)
    • 產(chǎn)生的結(jié)果是一個(gè)字符表達(dá)式
    • 使用連接操作符查詢,返回結(jié)果是一個(gè)連接后的結(jié)果(每個(gè)結(jié)果的連接)
    • select name || sex as new from student:將name和sex的查詢結(jié)果連接起來顯示并設(shè)置查詢結(jié)果對(duì)應(yīng)的列名為new
  • 簡單去掉重復(fù)的查詢結(jié)果

    • 使用distinct關(guān)鍵字可以是某列中重復(fù)的值不顯示
    • distinct操作會(huì)引起排序,通過排序去掉重復(fù)的記錄
    • distinct必須放在第一列的前面,只能實(shí)現(xiàn)單列去重
    • select distinct sex from student
  • 條件查詢

    • select 列名 from 表名 where 條件
    • where后面不能使用別名
  • 模糊查詢

    • 使用like運(yùn)算符進(jìn)行通配查詢
    • 查詢條件可以包含文字字符或數(shù)字
    • %:表示0或多個(gè)字符
    • _:表示一個(gè)字符

    select name from student where name like 'S%' :只顯示以S開頭的姓名
    select name from student where name like '_A%' :只顯示第二個(gè)字符為A的名字
    select naem from student where name like '%A_B%' :只顯示含有A_B的名字(\:轉(zhuǎn)義字符)

order by

  • 使用order by可以將記錄進(jìn)行排序
  • ASC:升序(默認(rèn)的),DESC:降序排列
  • order by 只能放到所有select語句的最后

select name,sex,age from student order by age asc:按照age進(jìn)行降序排列
select name,sex,age,sal from student order by age asc,sal desc:按照age降序排列,如果相等則在按照sal升序排列

單行函數(shù)

  • 用于操作數(shù)據(jù)項(xiàng)
  • 可以接受參數(shù)并返回一個(gè)值
  • 對(duì)每一個(gè)返回行起作用,每一行返回一個(gè)結(jié)果
  • 可使用轉(zhuǎn)換函數(shù)修改數(shù)據(jù)類型
  • 可使用嵌套形式
  • 常見的單行函數(shù)包括字符、數(shù)字、日期處理函數(shù)、類型轉(zhuǎn)換函數(shù)、邏輯處理函數(shù)等

字符函數(shù)

  • lower:將字符串全部變?yōu)樾?/p>

    select name,sex from student where LOWFR(name) = 'blake'; 查詢姓名為blake的相應(yīng)屬性,不管姓名是大小寫還是大小寫混寫的都能查出
    
  • upper:將字符串全部變?yōu)榇髮?/p>

  • initcap:將字符串的第一個(gè)字母變?yōu)榇髮?/p>

  • concat:將兩個(gè)字符串拼接起來

  • substr:截取字符串

    select substr('helloword',2,5) from dual;--從第二個(gè)開始數(shù)5個(gè)
    
  • length:返回字符串的長度

    select length(t.empfirstname) from employee t;
    
  • instr:在一個(gè)字符串中定位子字符串的位置(沒有的話返回值為0)

    select instr('hellword','w')from dual;--查詢w在hellword中的位置
    
  • 左補(bǔ)齊函數(shù)(lpad)

  • 右補(bǔ)齊函數(shù)(rpad)

    select e.empfirsname,rpad(e.empfistname,10,'&') from employees e;--設(shè)置長度為10,不夠的用&補(bǔ)齊
    
  • replace:替換函數(shù)

    select replace('ABCDFG','D','www') from dual;--用www替換D
    
  • trim(leading|trailing|both y from x):從x中截去單個(gè)字符y

  • both:截去兩邊的;leading:從左邊;traiing:從右邊

    select trim(both 'h' from 'hooojdhh') from dual;--截去兩邊的h
    

數(shù)值處理函數(shù)

  • 1.round:保留指定的位數(shù)(按四舍五入)

    SELECT round(5.75), round(5.75, 1), round(15.75, -1) FROM dual;--1代表保留一位小數(shù),-1表示個(gè)位也四舍五入
    
  • trunc:直接去掉小數(shù)點(diǎn),沒有四舍五入

    SELECT trunc(5.75), trunc(5.76, 1), trunc(15.75, -1) FROM dual;--1表示保留一位小數(shù),直接去掉后面的,不四舍五入
    
  • mod:去余數(shù)

    select mod(1600,300) from dual;--返回結(jié)果為100
    
  • abs:去絕對(duì)值

    select t.quotedprice -100 from order_details t where t.ordernumber =354 and t.productnumber = 13;--返回
    
  • sign(x)返回x的符號(hào)

若x<0,返回-1;若x=0,返回0;若x>0,返回1

  • floor(x)返回小于或等于x的最大整數(shù)

    select floor(5.8),floor(-5.6) from dual;
    
  • ceil(x)返回大于或等于x的最小整數(shù)

    select ceil(5.8),ceil(-5.6) from dual;
    
  • power(x,y)返回x的y次冪

日期處理函數(shù)

  • sysdate:返回系統(tǒng)的當(dāng)前時(shí)間

    select sysdate from dual;
    
  • add_months(x,y):返回x加上y個(gè)月的結(jié)果,如果y為負(fù)值,就是減去

    select add_months(sysdate,10) from dual;
    
  • last_day(x):返回包含x月的最后一天

    select last_day(date '1993-04-28') from dual;--返回結(jié)果為1993-04-30
    
  • next_day(x,day):從x時(shí)間開始,返回下一個(gè)day的時(shí)間值

    select next_day(sysdate,'星期一') from dual;--從系統(tǒng)的當(dāng)前時(shí)間開始,返回下一個(gè)星期一的日期
    
  • months_between(x,y):返回x和y之間有多少個(gè)月(x-y),可以是負(fù)數(shù)

    select months_between(sysdate,date '1993-04-28')/12 from dual;--計(jì)算出某個(gè)人的周歲
    
  • round(date,month/day):

Month 1-15日算上一個(gè)月,15日后算下一個(gè)月
Year 1-6月算上一年,7-12月算下一年

select round(date'2014-7-16','month') from dual;--返回2014-8-1 select round(date'2014-7-16','year') from dual;--返回結(jié)果為2015-1-1
  • trunc

    select trunc(date'2014-7-16','month') from dual;返回結(jié)果為2014-7-1
    

類型轉(zhuǎn)換函數(shù)

數(shù)據(jù)類型轉(zhuǎn)換包含隱士類型轉(zhuǎn)換和顯示類型轉(zhuǎn)換
隱士類型轉(zhuǎn)換:系統(tǒng)自動(dòng)轉(zhuǎn)換
顯示類型轉(zhuǎn)換:調(diào)用相應(yīng)的函數(shù)轉(zhuǎn)換

TO_CHAR:字符串轉(zhuǎn)換(其他類型轉(zhuǎn)換為字符串)
TO_NUMBER:數(shù)值轉(zhuǎn)換
TO_DATE:日期轉(zhuǎn)換

  • TO_CHAR

將日期轉(zhuǎn)換為字符串格式
必須用單引號(hào)括起來,大小寫不敏感
有一個(gè)fm元素,用于填補(bǔ)空格或者禁止前面的零
使用逗號(hào)分離日期
TO_CHAR(date,'fmt')
常用的日期格式:
YYYY:四位數(shù)表示的年
YEAR:拼寫出的年
MM:兩位數(shù)字的月
MONTH:全月明(例如:sepember)
DD:兩位數(shù)字表示的月
DAY:全天名

select name,TO_CHAR(hiredate,'fmDD Month YYYY') HIREDATE from emp
  • TO_NUMBER:將字符串轉(zhuǎn)化為數(shù)值TO_NUMBER(char)

    select * from emp where deptno = TO_NUMBER('30')
    
  • TO_DATE:將字符串轉(zhuǎn)換為日期TO_DATE(char,['fmt'])

    select TO_DATE('2006-05','YYYY-MM') from DUAL
    

通用函數(shù)

  • nvl(value,srt):如果第一個(gè)參數(shù)不為null,就返回第一個(gè)參數(shù),如果為null就返回第二個(gè)參數(shù)

    select nvl(e.name,'name is null') from employee e;
    
  • nvl2(value,x,y):如果value為null就返回y,否則返回x

    select nvl2(s.class_id,1,2) from students s;
    
  • nullif(x,y):如果相等返回null,不相等則返回x;

    select nullif(s.sex,'男') from students s;
    

case表達(dá)式:(選擇表達(dá)式)

Case國際sql通用支持的,使用case可移植更好。相當(dāng)于在SQL中執(zhí)行if語句 CASE 可用于允許使用有效表達(dá)式的任意語句或子句。 例如,可以在 SELECT、UPDATE、DELETE 和 SET 等語句以及 select_list、IN、WHERE、ORDER BY 和 HAVING 等子句中使用 CASE。

select e.salary,
case e.type_id
   when 1 then e.salary*2 
   when 2 then e.salary*3
   when 3 then e.salary*4 
    eles e.salary*5
end 
as new_salary from employee e;

說明:當(dāng)typeid為1時(shí),薪水2,當(dāng)typeid為2時(shí),薪水3,當(dāng)type_id為3時(shí),薪水4,其他情況下薪水5;

組(聚合)函數(shù)

  • max(),min().avg():注意單行與多行不能放在一起

    select max(e.aslary),e.type_id from employee e;--會(huì)直接報(bào)錯(cuò)的,單行結(jié)果與多行不能放在一起
    
  • count:統(tǒng)計(jì)函數(shù) : 統(tǒng)計(jì)字段時(shí)不統(tǒng)計(jì)null的

    select count(*) from employee;--統(tǒng)計(jì)該表一共有多少條記錄(里面加任意的數(shù)字也可以count(2))
    select count(e.manager_id) from employee e;--按照某個(gè)字段統(tǒng)計(jì),空值不統(tǒng)計(jì)
    
  • group by:分組
    結(jié)合分組函數(shù)使用
    group by后面的列可以不出現(xiàn)在select后邊,但出現(xiàn)在select后面的列必須出現(xiàn)在group by子句里面
    如果select列表中既有普通列又有分組函數(shù),則必須使用group by子句
    聚合分組函數(shù)的條件限定不能使用where,只能使用having,且用了having必須使用group by。

    select e.division*id,avg(e.salary) from employees2 e group by e.division*id;--求每個(gè)部門的工資
    

語法的執(zhí)行順序

1.select 2.from 3.where 4.group by 5.組函數(shù) 6.having 7.order by

說明:having與where功能一樣,就是執(zhí)行的順序不一樣eg:select e.division_id,avg(e.salary) from employees2 e group by e.division_id where avg(e.salary)>150000;--會(huì)報(bào)錯(cuò)的,因?yàn)閣here比組函數(shù)(avg)先執(zhí)行,在執(zhí)行where的時(shí)候,avg(e.salary)還沒有算出來,所以會(huì)出錯(cuò),換成having就沒事了。

  • insert into(插入語句)
    插入時(shí)注意完整性約束條件(外鍵的取值)
    插入的時(shí)候插入到首行

    insert into 表名(插入的字段)values(字段對(duì)應(yīng)的值)
    insert into student values(3,'name','sex',12); 
    insert into student(id,name) values(4,'name'); 
    insert into student values(5,'''name','sex',12);
    

插入的名字為'name insert into student(name,sex) values(&Name,'nan');
&:變量,在執(zhí)行該語句時(shí),會(huì)讓你輸入name要插入的值(Name變量名自己起的) 一次插入多條語句,要查入得值從另一個(gè)表中取數(shù)據(jù) insert into student(name,sex,age) select name,sex,age from student2 where id>10;

  • delete(刪除語句) : delect from 表名 條件

    delect from student where id=3
    
  • update(修改語句) : update 表名 set 字段名=要修改的值 條件

    update student set name=gfdd where id=2;
    update studnet set name=gggg,sex=nv where id=3;
    

事務(wù)

一組sql語句一塊執(zhí)行,要么一起成功,要么一起失敗 以commit開始

  • commit:提交eg:commit

  • rollback:回滾(撤銷)eg:rollback

    commit;select * from customers;insert into customers values(6,'gfd','red',date '1993-04-28',null);
    insert into customers values(7,'gfd','red',date '1993-04-28',null);
    savepoint A;--添加保存的點(diǎn),回滾時(shí)可以指定到該位置
    insert into customers values(8,'gfd','red',date '1993-04-28',null);
    savepoint B;
    insert into customers values(9,'gfd','red',date '1993-04-28',null);
    rollback to A;--回滾到A點(diǎn)
    

鎖:保證數(shù)據(jù)庫的一致性(同步):自添加鎖

T1執(zhí)行 update students set name='gfd' where id=3; 如果T2想修改id=3的數(shù)據(jù),必須等T1提交后才能修改(也就是說提交后自動(dòng)釋放鎖)

死鎖

T1 update students set name='gfd' where id=3;
update students set name='gfd' where id=4; T2 update students set name='gfd' where id=4; 
update students set name='gfd' where id=3; 

說明:在T1,T2執(zhí)行完第一條語句時(shí),再執(zhí)行下一條語句時(shí),都被各彼此鎖著,所以都不能執(zhí)行下去了。 就出現(xiàn)了死鎖的狀態(tài),oracle數(shù)據(jù)庫會(huì)自動(dòng)解鎖一條語句

DDL語句(數(shù)據(jù)定義語言)

對(duì)表的操作可以通過DDL語句進(jìn)行,包括:

  • create:創(chuàng)建新表,必須以字母開頭,訪問其他用戶的表時(shí)需要加上用戶名的前綴

    create table dept(deptno number(2),dname varchar2(14),loc varchar2(3));
    create table dept30 as select empno,ename,sal*12 ANNSAL,hiredate from emp where deptno=30;--數(shù)據(jù)從別的表中拷貝
    
  • 創(chuàng)建聯(lián)合主鍵的表

    create table emp( emp_id integer, emp_name varchar2(20) not null, emp_bir date default sysdate primary key(emp_id,emp_name) );
    
  • alter:更改表的結(jié)構(gòu)(字段)

alert table 表名 add (增加的列名 類型,。。。。。);--增加列
alert table 表名 modify (修改的列名 類型);--修改列
alert table 表名 rename column 要修改的列名 to 新的列名;--修改列名
alter table 表名 rename to 新的表名;--修改表名
alert table 表名 drop column 要?jiǎng)h除的列名;--刪除列
alert table dept30 add (job varchar2(9));
alert table dept30 modify (job varchar2(15));
alert table dept30 raname column deptname to dname;alert table dept30 drop column job;

  • drop:刪除表

表中的所有數(shù)據(jù)將被刪除
事物被自動(dòng)提交
所有的索引被刪除
不能回退
徹底刪除表
drop table 表名;--刪除指定的表

  • truncate:快速刪除表中的所有記錄

直接刪除全部的記錄,無法指定刪除條件
無法回退
只會(huì)刪除數(shù)據(jù),會(huì)保留表的結(jié)構(gòu)(字段),可以再次插入數(shù)據(jù)
速度快于delect
truncate table 表名;--刪除指定的表

約束條件

  • primary key(主鍵約束)

    • 在創(chuàng)建的表的時(shí)候指定

      create table emp(emp_id integer primary key)
      
    • 在表創(chuàng)建完成后添加主鍵約束

      alter table stu add primary key (emp_id);
      
  • foregin key(外鍵約束)

    • 兩張表沒有建立外鍵關(guān)系

      alter table stu add foregin key(stu_id) references xi(xi_id)
      
    • 刪除外鍵的時(shí)候,相應(yīng)表中與該外鍵的有關(guān)的記錄也全部刪除

      alter table stu add foregin key(stu_id) references xi(xi_id) on delete cascade
      
    • 刪除外鍵的時(shí)候,相應(yīng)表中與該外鍵的有關(guān)的列全部設(shè)置為null

      alter table stu add foregin key(stu_id) references xi(xi_id) on delete set null
      
  • unique(不能重復(fù)約束)

    alter table emp add unique(emp_name);--可以插入null(null值可以重復(fù))
    
  • check(取值范圍約束)

    alter table emp add check(em_sex in ("男","女"));alter table emp add check(em_id>0);
    

索引

使用索引大大加快查詢的速度
對(duì)數(shù)據(jù)量大的,經(jīng)常使用的表才去創(chuàng)建索引(需要維護(hù)的)
查詢的時(shí)候與正常的一樣

create index 索引名 on 表名(字段名。。。。);--創(chuàng)建索引delete index 索引名;--刪除索引

視圖

可以隱藏一些信息
虛擬的表(不真實(shí)存在,基表的數(shù)據(jù)刪除時(shí),視圖中的數(shù)據(jù)也會(huì)刪除)
可以進(jìn)行增刪改查(對(duì)視圖表中的數(shù)據(jù)改變時(shí),基表的數(shù)據(jù)也會(huì)改變)
只要視圖中能看到的,基表中肯定能看到

create or replace view ch_view as select * from products p where p.price<15;--創(chuàng)建視圖
select * from ch_view;--查詢視圖insert into ch_view values(14,3,'fff','ggg',12);--插入數(shù)據(jù)

添加注釋

comment on table 表名 is ‘注釋’;--表添加注釋
comment on column 表名.字段名 is ‘注釋’;--字段添加注釋

多表聯(lián)合查詢

沒有指定連接條件的多表查詢將造成笛卡爾積的結(jié)果
笛卡爾積結(jié)果:兩個(gè)表中所有數(shù)據(jù)的集合都會(huì)查詢出來

笛卡爾積

多表連接查詢中的連接類型

內(nèi)連接:返回符合特定連接條件的查詢記錄
  • 等值連接:返回符合指定連接條件的值,這些值是相等關(guān)系

    select * from products p,product_type pt where p.type_id = pt.type_id;
    select * from products p inner join prodect_type on p.type_id = pt.type_id;--inner join on 條件
    
  • 非等值連接:返回符合指定連接條件的值,這些值不是相等關(guān)系

    select * from products p,product_types pt where p.product_type_id <> pt.product_type_id;--<>:不等于
    
  • 自然連接:特指在同一張表內(nèi)通過特定連接條件查詢符合連接條件的值

select * from products p natural inner join purchases pt;--自動(dòng)按著相等的去連接,不用加條件了 在emp中每一個(gè)員工都有自己的mgr(經(jīng)理),并且每一個(gè)經(jīng)理自身也是公司的員工,自身也有自己的mgr。我們需要將每一個(gè)員工自己的名字和經(jīng)理的名字都找出來。
select worker.ename,'work for',manager.ename from emp worker,emp managetr where worker.mgr = manager.empne work for:連接字符串
外連接:不僅返回符合連接條件的記錄,也返回指定表中的不符合連接條件的記錄
  • 左外連接:先對(duì)A表和B表做內(nèi)連接,再把A表中沒有匹配的結(jié)果集添加進(jìn)去形成新的結(jié)果集(相應(yīng)的右表的值(對(duì)應(yīng)A表沒有匹配的)為null)

    select * from newdept left outer join newemp on newdept.deptid = newemp.deptid;--outer可以省略 
    。。。。。。。where a.deptno = b.deptno(+);--左連接
    
  • 右外連接: 先對(duì)A表和B表做內(nèi)連接,再把B表中沒有匹配的結(jié)果集添加進(jìn)去形成新的結(jié)果集(相應(yīng)的左表的值(對(duì)應(yīng)B表沒有匹配的)為null)也返回

    select * from newdept right outer join newemp on newdept.deptid = newemp.deptid
    。。。。。。。where a.deptno(+) = b.deptno;--右連接
    
  • 全外連接:在內(nèi)連接的基礎(chǔ)上,把左右兩表中不符合連接條件的記錄都返回

在emp中每一個(gè)員工都有自己的mgr(經(jīng)理),并且每一個(gè)經(jīng)理自身也是公司的員工,自身也有自己的mgr。我們需要將每一個(gè)員工自己的名字和經(jīng)理的名字都找出來。

  select worker.ename,'work for',manager.ename from emp worker,emp managetr 
  where worker.mgr = manager.empnework for:連接字符串

用SQL語句列出EMP表中所有部門的詳細(xì)信息以及對(duì)應(yīng)的部門人數(shù)

select a.* , b.* from dept a,(select deptno,count(*) from emp group by deptno) b where a.deptno = b.deptno(+)
  • 全外連接

用SQL語句列出NEWEMP表和NEWDEPT表中所有部門和員工的詳細(xì)信息:

select * from newdept full outer join newemp on newdept.deptid = newemp.deptid

集合

集合中的元素可以把一條記錄或者一個(gè)字段當(dāng)做一個(gè)元素
用了集合再排序的時(shí)候,order by 字段的位置(例如 1):只能用數(shù)字了

  • intersect:交集

  • minus:減集

    • 在一張表中顯示了,就不在另一張表中出現(xiàn)了(A表 minus B表):顯示B表去除與A表相同的部分
  • union all:并集(加all不去重)union :去重

    select * from (select * from (select * from employees2 e order by e.salary desc) where rownum<11
    minus
    select * from (select * from employees2 e order by e.salary desc) e where rownum<4) order by 6;--用到了集合再排序只能使用數(shù)字了
    

經(jīng)典例子

根據(jù)時(shí)間統(tǒng)計(jì)勝負(fù)數(shù)
執(zhí)行sql語句變成為:
select
 t_date, 
 (select count(*) from t where t_status='勝' and t_date=e.t_date) 勝, 
 (select count(*) from t where t_status='負(fù)' and t_date=e.t_date) 負(fù)
from t e group by t_date order by e.t_date;
兩張表中的數(shù)據(jù)運(yùn)算
select kc.mc "種類",kc.s1-(select sum(s1) from ck where ck.mc = kc.mc ) "剩余量" from KC;
一次修改多條記錄
update employees e set e.salary = 
case e.employee_id
  when 1 then 5555
  when 2 then 6666
end
where e.employee_id<3;

多表聯(lián)查

購買數(shù)量超過一個(gè)的產(chǎn)品名,顧客名以及購買的數(shù)量(3張表)
select * from products;
select * from customers;
select * from purchases;

  • 第一種方法

    select * from customers c inner join (select * from products p inner join purchases pr on p.product_id=pr.product_id) a on a.customer_id=c.customer_id where a.quantity>1;
    
  • 第二種方法

    select * from (products p inner join purchases pr on p.product_id=pr.product_id and pr.quantity>1) inner join customers c on c.customer_id=pr.customer_id;
    
  • 第三種方法

    select * from products p,purchases pr,customers c where p.product_id=pr.product_id and pr.customer_id=c.customer_id and pr.quantity>1;
    

四表聯(lián)查

有如下幾張表:

部門表:organization(orgid ,orgName)
商品表:Goods(goodsid,goodsName)
銷售單(單頭):sale(billid,billdt,orgid,status)
銷售單(單體):sale_item(billid,goodsid,qty)

orgid:組織編碼;
orgName:組織名稱;
billid:單據(jù)編號(hào)
billdt:訂單日期

查詢“銷售一部”本月的商品銷售明細(xì)(商品編碼。商品名稱,銷售日期,銷售數(shù)量)

select * from organization o,goods g,sale s,sale_item si 
where 
o.orgid=s.orgid and g.goodsid=si.goodsid ands.billid=si.billid and orgName="銷售一部" and billdt>trunc(sysdate) and billdt < last_day(sysdate);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ORACLE自學(xué)教程 --create tabletestone ( id number, --序號(hào)usernam...
    落葉寂聊閱讀 1,255評(píng)論 0 0
  • Oracle筆記系列這幾篇是來自一位老師的筆記,分享給大家放在簡書上,主要方便自己時(shí)常復(fù)習(xí),還有學(xué)習(xí)Oracle的...
    panda_Hi閱讀 922評(píng)論 0 1
  • 今天哥哥12歲啦\(≧≦)/,好開心啊! 昨晚我們一家人去接哥哥回家慶生,先和哥哥去市場(chǎng)買火鍋料,大冷天你當(dāng)然回家...
    瑩影相隨閱讀 386評(píng)論 2 4
  • 不知不覺中 我們相識(shí)9年了 一路上 我看著你戀愛 看著你結(jié)婚 看著你晉升為準(zhǔn)媽媽 每一次角色的轉(zhuǎn)變我都有參與其中 ...
    木香姑娘閱讀 460評(píng)論 0 0
  • music.163.com/#/search/m/ “我想要做個(gè)思想上的女流氓 生活上的好姑娘 外形上的柔情少女 ...
    齊紓閱讀 601評(píng)論 4 3

友情鏈接更多精彩內(nèi)容