sql日常總結
阿新 • • 發佈:2018-12-14
一、sql基礎
- 查詢city欄位以A或L或N開頭的資料
SELECT * FROM Persons WHERE City LIKE '[ALN]%'
- 查詢city欄位不以A或L或N開頭的資料
SELECT * FROM Persons WHERE City LIKE '[!ALN]%'
- 連線符
select concat(id,’的學號’,cardno,’的卡號’); #Mysql語法
select 'hello'||'oracle' test from dual; #Oracle語法(oracle也可以用上邊的concat)
- 字串
select substr('hello',0,3) from dual --下標1與0效果一樣 結果:hel select length('hello') from dual --結果:5 select replace('hello','l','x') from dual --結果:hexxo
- 數值
select round(45.926,2) from dual --45.93 四捨五入
select trunc(45.926,2) from dual --45.92 截斷
select mod(1600,300) from dual --100
- 日期
select ename,round((sysdate-hiredate)/7) from emp –入職週數 select ename,round(months_between(sysdate,hiredate)) from emp --入職月數 select add_months(sysdate,3) from dual --3個月後的日期 2018/3/26 21:29:19
- to_char函式
select ename,to_char(hiredate,'yyyy-mm-dd') from emp --1981--02—20
select ename,to_char(hiredate,'fmyyyy-mm-dd') from emp --1981-2-20
select to_char(sysdate,'yyyy-mm-dd hh :mi:ss') from dual—分鐘是mi
- to_number函式
select to_number('10')+to_number('12') from dual --將字串轉換為數字 --查詢1980和1985年入職的員工 select * from emp where to_char(hiredate,'yyyy')=1980 or to_char(hiredate,'yyyy')=1985
- to_date函式
select * from emp where hiredate between '1890-01-01' and '1982-12-31' #mysql語法
#oracle不能像上邊那樣寫,因為hiredate是日期型別,與字串型別匹配不上
select * from emp where hiredate between to_date('1980-01-01','yyyy-mm-dd') and to_date('1980-12-31','yyyy-mm-dd') #oracle語法
- decode函式(只有oracle有該函式)
select job, decode(job,
'CLERK', '業務員',
'SALESMAN','銷售員',
'其他'
) from emp;
#以下語法(case/when)可以替換是那個邊的表達
select job,
case job
when 'CLERK' then '業務員'
when 'SALESMAN' then '銷售員'
else '其他'
end
from emp;
- 約束
create table person(
pid number(5),
pname varchar2(30) not null,
gender number(1),
tele varchar2(11) ,
constraint pk_pid primary key(pid),-- constraint後是起的名字
constraint check_gender check(gender in(0,1)),--性別只能是1或2
constraint unique_key unique(tele)
)
- 外來鍵
create table orders( --訂單
oid number(5) primary key,
totalprice number(8,2)
)
create table orderdetail( --訂單項 鍵盤,滑鼠是兩個訂單項,屬於同一訂單
oidid number primary key,
price number(8,2),
name varchar2(30),
oid number(5),--外來鍵
constraint fk_orderdetail_orders foreign key(oid) references orders(oid)
);
- 聚合函式不能寫在where之後
SELECT city FROM weather WHERE temp_lo = max(temp_lo); #語法錯誤,修改為如下寫法是正確的
SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather); #語法正確
- where與having的區別
WHERE在分組和聚合計算之前選取輸入行(它控制哪些行進入聚合計算);而HAVING在分組和聚合之後選取輸出行。
因此,WHERE 子句不能包含聚合函式;因為試圖用聚合函式判斷那些行將要輸入給
聚合運算是沒有意義的。 相反,HAVING子句總是包含聚合函式。當然,你可以寫不使用聚合的HAVING 子句,但這樣做沒什麼好處,因為同樣的條件用在WHERE階段會更有效。
二、資料型別
- 浮點型
float(m,d); #單精度浮點型 8位精度(4位元組) m總個數,d小數位
double(m,d); #雙精度浮點型 16位精度(8位元組) m總個數,d小數位
- char與varchar
char:
固定長度;例如某欄位定義為10個長度,該欄位存了一個漢字”是”,這個漢字佔兩個字元,剩下八個字元會自動填滿;最大長度255,長度沒有預設長度,必須顯式指定長度
varchar2:
長度不固定,同上,剩下八個用不到的字元空間會釋放出去。Varchar2與mysql裡的varchar一樣;最大長度3999(即可以放2000箇中文或3999個英文),沒有預設長度,必須指定長度;
- number
number:預設長度是8
number(3):存的最大數是999
number(3,2):存的最大數是9.99
- date:
相當於mysql裡的datetype,mysql裡的date只有年月日,datetype還包括時分秒
- timestamp:
也是日期型別,相對於date來說,精度高,最多可以保留到秒後9位小數
- long
相當於mysql裡的longtext,即大文字,可以支援兩個G
- clob:
可以放四個G內容
- blob:
可以放四個G內容,存放電影,圖片等;
- 定點數
#浮點型在資料庫中存放的是近似值,而定點型別在資料庫中存放的是精確值。
decimal(m,d) 引數m<65,指的是總個數;d<30且 d<m,指的是小數位個數。
三 、注意點
- union與union all
UNION 結果集中的列名總是等於 UNION 中第一個 SELECT 語句中的列名。
- 刪除資料——delete與truncate
delete from person where name=’tom’;# delete from person刪除全部資料;
truncate person; # 刪除全部資料
delete:可以回滾,也可以閃回;
delete刪除會產生磁碟碎片,且不釋放空間;truncate不會產生磁碟碎片;
truncate先摧毀表結構,再重構表結構;delete只刪除資料而已;
- savepoint事物儲存點
insert into person(pid,pname,gender,tele) values('1','tom','1','13222229090');
savepoint a;
update person set tele='1111111111' where pid='1';
savepoint b;
select * from person;
rollback to a; #回滾到事物儲存點a之前
- 檢視 view 檢視可以理解為一個虛表,封裝了一條複雜的查詢語句,檢視可以隱藏敏感列; 語法:create view 檢視名 as sql查詢語句(最後是複雜的sql查詢語句,可以用括號括起來)
先登入管理員使用者,為當前使用者(scott)提供建立檢視的許可權:grant create any view to scott;
create view person_view as (select pname from person where pid='1');#建立檢視
select * from person_view;--查出來的是姓名
#優點:隱藏敏感列:比如隱藏工資與獎金列
create view view_emp as(select empno,ename,job,mgr,hiredate,deptno from emp)
select * from view_emp;
修改(update)檢視的話,會將視圖裡涉及到的表資料修改,所以一般建立檢視時將檢視設計成只讀:
create or replace view person_view as (select pname from person where pid='1') with read only; #此時該檢視就不能update了
- 序列——sequence auto increment語法只有mysql有,oracle沒有;序列主要是做主鍵自增的,是獨立於表之外的物件;
create sequence seq_person; --建立序列,沒有與任何表產生關係,獨立於表之外
select seq_person.nextval from dual --1 每執行一次,得到的結果依次加1
select seq_person.currval from dual --檢視當前的值
insert into person(pid,pname) values (seq_person.nextval,'tom');
# 序列一般單表單用,有幾個表就建立幾個序列,如果多個表操作同一張表的序列,容易出現斷層;
建立序列的複雜語法如下:
create sequence test
minvalue 3 --最小值,預設是1
increment by 2 --步增值,預設1
start with 5 --起始值,預設1
maxvalue 20 --最大值,預設值是18個9。不做迴圈的話,超過最大值會報錯
cycle --迴圈 預設是nocycle
cache 5 --快取,預設快取的數是20(快取在記憶體裡),這裡的值必須小於每次迴圈出來的數的個數
select test.nextval from dual;上邊的複雜語法不能做主鍵自增,主鍵會衝突;即序列主要是做主鍵自增,也可以做其他事;
- 索引——index 也是獨立於表之外的物件;作用是提高查詢效率(相當於書的目錄);
使用索引規則:
1、表裡的資料經常被修改的話,不適合建索引;
2、資料量小時不用建立索引;
3、某些欄位不會被當成條件做查詢時,沒有必要建立索引
語法:create index 索引名 on 表名(欄位名);
eg: create index index_emp_ename on emp(ename);
select * from emp where ename='SMITH'; --建索引前後查詢所花的時間:0.031 0.016
資料少的話效果不明顯,下邊建立500萬條資料
create table t_test(
tid number,
tname varchar2(30)
)
begin
for i in 1..5000000
loop
insert into t_test values(i,'測試資料'||i);
end loop;
end;
create index test_index on t_test(tname);
select * from t_test where tname='測試資料4565558';#這樣資料量大的話效果會很明顯;
複合索引:對錶裡多個欄位做索引
create index index_emp on emp(ename,job);# 注意,此時只有將ename,job同時作為查詢條件時才會用到索引,不然不會用到索引的,比如select * from emp where job='' and hiredate=''是不會用到索引的;
- 同義詞
給使用者分配建立同義詞的許可權:grant create synonym to scott;
同義詞相當於別名;
使用場景:一個使用者下想訪問另一個使用者下的某張表,可以這樣寫:
select * from scott.emp;
此時為了訪問方便,可以建立同義詞:create public synonym emp for scott.emp --public 可以不寫
以後查詢時:select * from emp;
刪除同義詞:drop public synonym emp --如果上邊加了public,這裡也要加上
- 資料匯入匯出 用於資料備份;
1、 exp system/root full=y; # 整庫匯出,基本不用;
2、按使用者匯入匯出:把scott使用者下的資料匯入maltose01使用者下:
注意:使用exp與imp這兩個命令的話,電腦上必須安裝oracle軟體,所以下邊的命令需要在虛擬機器裡執行
--先匯出
exp scott/[email protected]:1521/orcl file='c:\scott.dmp'
--再將上邊的資料匯入到另一個使用者
imp maltose01/[email protected]:1521/orcl file='c:\scott.dmp' full=y
3、按表匯入匯出(plSql工具右鍵表就能匯出該表)
--先匯出
exp scott/[email protected]:1521/orcl file='c:\scott.dmp' tables=emp,student,teacher
--再匯入到另一個使用者
imp maltose01/[email protected]:1521/orcl file='c:\scott.dmp' full=y tables=emp,student,teacher