oracle 學習

sqlplus /as sysdba登陸
spool c:\基本查詢.txt--清屏 host clear(linux)
host cls

showuser查看當前用戶

select *from tab 數據字典,管理員給我們提供的表

exit 退出命令行

desc emp 查詢表結構信息

setlinesize 120表示每一行顯示120個字符

col namefor a8 表示8個字符 a字符

cols salfor 9999

/ 表示執行上一條sql語句

Sql優化:

儘量使用列名代替*,因爲使用*,需要解析所有的列名

但是在oracle 9i之後,他們兩個是一樣的,

修改錯誤的sql語句

-c命令 change

2*form emp

c/form/from

ed會把sql語句存入一個文件並打開

3種別名的方式(別名之間如果有空格、sql關鍵字就必須要添加雙引號)

selectsal,sal*12name as “姓名age “年齡sex 性別, from emp


selectsalsal*12 年薪,comm 獎金,sal*12+comm 年收入 from emp

如果獎金沒有年收入就爲0了,

Sql語句中的null

包含null的表達式都爲null

Sqlnull != null

控制是無效的,未指定的,未知的或不可預知的值

Sal * 12 +nu1(comm0)//如果commnull,就返回0

查詢獎金爲null的員工

Select * from emp where comm=null這是不對的

Select * from emp where comm Is nullis not null

Select distinct name from emp

Select distinct deptnojob from emp

Distinct作用於後面所有的列

Sql語言大小寫不敏感


連接符:

concat鏈接字符串 selectconcat(‘hello’,’world’) from emp

如果emp14條記錄,就會顯示14條語句

select concat(‘hello’,’world’) from dual

dual表:僞表,是管理員提供的,不是我們創建的

sql 99 ANSI發佈的標準所以oracleselect後面必須有from,而mysql可以沒有

select‘hello’| | ‘world’from dual;//helloworld

selectename | |’的薪水是’ | | sal fromemp

sql語句與sql*plus命令:

SQL:一種語言

ANSI的標準

關鍵字不能縮寫

使用語句控制數據庫中的表的定義信息和表中的數據

SQL*PLUS:一種環境

oracle的特性之一

關鍵字可以縮寫

命令不能改變數據庫中的數據的值

集中運行

Selectupdateinsertdelete

DescCol setedchangesql plus語句

使用isql*plus可以:(就是sql plusweb版,11g之後就沒有)

描述表結構

Savec:\a.sql

@c:\a.sql加載並且執行

Loadc:\a.sql加載不執行

Spooloff //剛纔操作的所有步驟將被記錄,也就是錄屏命令



過濾:

Select * from emp where empno=10

Oracle中字符串大小寫和日期格式敏感

1981-11-17不叫日期,17-11-81符合格式,oracle數據庫中默認

DD-MON-RR格式的日期,是oracle9i之後的格式,9i之前DD-MON-YY1998-20982098-98

千年蟲問題,DD-MON-RR解決了這個問題,

查詢當前時間

selectnow()//mysql

selectsysdate from dual;//oracle

--查詢系統參數

Setlinesize 150

Col parameter for a20

select *from v$nls_parameters; // v$nls_parameters數據字典

--修改日期格式

Altersession | globle(全局)setNLS_DATA_FORMAT =’yyyy-mm-dd’

<<=>between and(含邊界,小的在前,大的在後面)inlikeis null

Select *from emp where depot in(10,20); not in(10,20)

那麼inset)這個集合裏面能不能有null值呢?如果集合中含有null,不能使用not in操作符,但是可以使用in操作符

Like表示的是模糊查詢 %任意長度的任意字符串_ 任意的字符串

查詢名字是四個字的員工 select * from emp where enamelike ‘_ _ _ _’.

查詢名字中含有下劃線的員工

select * from emp where ename like ‘% \ _%’escape ‘\’;

select * from emp where ename like ‘% a_%’escape ‘a’;

rollback;// 回退,可以做這一步的原因就是前面做的事在一個事務中,mysql中通過start Transaction 開啓事務,oracle自動開啓的事務。


And 邏輯並 or 邏輯或not 邏輯否

Sql優化第二點:

Where condition1 and condition2

Where condition2 and condition1

這兩句執行的結果是一樣的嗎,但是性能不一樣。

Oracle解析where條件的時候是從右至左,對於and條件把有可能爲false的條件放在右邊,因爲右邊第一個爲false,其他的就不會執行

可以使用括號改變優先級


Order by字句 ascend (升序)descend(降序)默認是升序--

--a命令 append

adesc//a後面至少加上兩個空格,因爲如果一個的話就默認在sql後面加上desc

order by 後面+列名、表達式、別名、序號

order bysal * 12 + ny1(comm.,0)

selectcomm. As ‘年收入’fromemporder by “年收入

order by4//第四列列數不能超過表中的總列數


order by後面可以有多列嗎?

Order bydeptnosal ;這樣排序作用於所有的列,如果第一列相同,則按照第二列排序

Order bydeptnosal desc // 這樣desc是作用於離他最近的一列,如果都要降序

Order bydeptno desc sal desc


按照獎金排序(獎金有可能爲null

Setpagesize 20//每一頁顯示的條數

Order bycomm.// 升序是沒有問題的

Order bycomm. desc;這樣的話 comm.null的都會在前面,而有數據的在後面進行排序

Order bycomm. desc nulls last // 這樣就可以解決null在後面,oracle有,這個不符合sql 99





函數;

單行函數:一個輸入、一個輸出,只對一行進行變換。

多行函數:多個輸入、一個輸出


單行函數:字符、數值、日期、通用、轉換等


字符函數:

大小寫控制函數:lowerupperinitcap(首字母大寫)

字符控制函數

concat

substra,ba中,第b位開始取)(abcc位)、

length(字符數)|lengthb(字節數)、instrab在一個串中查找字串,返回下標,從1開始,否則返回0)、lpad|rpada10‘*’10位多餘的*填充,左填充、又填充)、trim(去掉前後指定的字符)、replace

trim(‘H’ from ‘Hello’)

replace (‘hello’,’l’,’L’)

數字函數:

Round 四捨五入

Round (45.926,2)--45.93 小數點後兩位

Round (45.926,-1)-- 50

Round (45.926,-2)--0

Trunc 截斷

trunk(45.926,2)--45.92

trunk(45.926,0)--45.92

trunk(45.926,-1)--40

trunk(45.926,-2)--0

Mod 求餘mod(1600,300)--100



日期:

Oracle中的日期類型數據實際含有兩個值:日期和時間

默認的日期格式DD-MON-RR

Select to_char(sysdate,’yyyy-mm-ddhh24:mi:ss’) from dual;

selectto_char(systimestamp,’yyyy-mm-dd hh24:mi:ss*ff’)from dual

日期的數學運算:

在日期上加上或減去一個數字結果爲日期(但是不允許日期+日期,因爲今天加上明天沒有任何意義)

Select (sysdate-1),sysdate,sysdate+1from dual;

在兩個日期相減返回日期之間相差的天數

Selectename,hiredate,(sysdate-hiredate),(sysdate-hiredate)/7星期,(sysdate-hiredate)/30,(sysdate-hiredate)/365.

可以用數子除24來向日期中加上或減去小時

日期函數;

Months_between兩個日期相差的天數

Add_month指定日期上加上若干月數

Next_day指定日期的下一個日期select next_day(sysdate,7)下個禮拜的今天

Last_day本月的最後一天

Round日期四捨五入

Trunk日期截斷


Selectmonths_between(sysdate,hiredate)(相減) 算準工齡

快照 snapshot 給數據庫拍個照片,數據庫出問題後可以恢復

Now date----- 25-7-95

round(sysdate,’MONTH’)--à01-8-95

round(sysdate,’YEAR’)---à 01-1-96

trunk(sysdate,’MONTH’)--à01-7-95

trunk(sysdate,’YEAR’)--à01-1-95


日期格式的元素:

YYYY 2011

YEAR

MM 04

MONTH4

DY|DAY 星期一

DD02


轉換函數:

隱性:’123’à123(有一個前提:被轉換對象是可以轉換的)

Varchar2 --à number

Varchar2 --à date

Char--ànumber

Char--àdate

To_char(123) to_number(‘123’)to_date

顯性:

Select to_char(sysdate,’yyyy-mm-ddhh24:mi:ss “今天是” day’)

To_char(number,’fomat’)

9數字0$美元L本地貨幣.小數點,千位符

查詢員工的薪水,貨幣符號,兩位小數

Selectsal,to_char(sal,’L9,999.99’)-à25982,598.00

???to_number

通用函數;

Nvl(a,b)慮空函數anull時返回b

Nvl2(a,b,c)anull時返回c否則返回b

Nullif(a,b) a==b時返回null,否則返回a

Coalesce(a,b,c...)從左至右找到第一個不爲null的值返回

條件表達式;

SQL語句中使用if-then-else邏輯

使用兩種方法:

Case表達式:sql99的語法類似Basic,比較繁瑣

Decode函數:oracle自己的語法,類似java

Case expr when expr1 then return_expr1

[whenexpr1 then return_expr1

Else else_expr

]

End

Decode(col|expred,search1,result[search1,result][default])

根據職位漲薪水(總裁1000、經理400、其他100

Select ename,job,sal,case job when‘president’ then sal+100

When‘manager’ then sal+400

Elsesal+100

End ‘漲後薪水

Selectename,job,sal,decode(job,’president’,sal+1000,

‘manager’,sal+400,

Sal+100) ‘漲後薪水


使用decode函數:根據80號部門員工的工資,顯示稅率

Selectlast_name,sal,decode(trunk(sal/2000,0),

0,0.00,

1,0.09,

2,0.20,

3,0.30,

0.45) tax_rate

From employees

Where depart_id = 80



分組函數:作用於一組數據,並對一組數據返回一個數據

Avg

Count

Max

Min

Sum

組函數會自動慮空,只會統計非空的數據

Count(*) count(nvl(comm,0))

Count(distinct dept_id)

Group by

select列表中所有沒有包含在組函數中的列都應該包含在groupby後面

包含在group by中的列不必包含在select列表中

求各個部門的平均工資

Select depno,avg(sal) from emp group bydepno

Select depno,depname,avg(sal) from empgroup by depnomysql

Select depno,depname,avg(sal)

from emp

group by depno,depname(oracle)

如果group by後面有多列怎麼分組呢?

先按照第一列分,如果第一列相同,再按照第二列、、、、

上述語句的效果是按照部門中的每個職位分組

不能再where字句中使用組函數

Having:把滿足條件的結果選出來,前提條件是必須要分組(過濾分組)

求出部門平均工資大於2000的部門

Selectdeptno,avg(sal)

Fromemp

Groupby deptno

Havingave(sal)>2000;

SQL優化三:

Having where 的區別

10號部門的平均工資

Select deptno,avg(sal)

From emp

Group deptno

Having deptno = 10;


Selectdeptno,avg(sal)

From emp

wheredeptno = 10;

如果havingwhere在業務中都可以儘量使用where,效率高於having

Where是先過濾再分組(先選出10號,再求)

Having是先分組再過濾(先對全部的分組,再過濾10號)

有一種情況例外只能使用having:如果條件中含有組函數只能使用having

嵌套組函數max(avg(sal))

Group by 語句增強

按照部門統計個部門不同工種的工資情況,要求如下:

Deptnojobsum(sal)

10clerk1300

Manager2450

3750

20clerk1900

Manager2692

7592

11342


Group by deptno,job

+

Group by deptno

+

Group by null

=

Group by rollup(deptno,job)

同理:

Group by rollup(deptno,job)

=

Group by deptno,job

+

Group by deptno

+

Group by null


Break on deptno skip 2// depto分段,跳躍空2

Select depot,job,sum(sal)

From emp

Group by rollup(deptno,job)


多表的查詢:

笛卡爾積:

Table1205table2 82

笛卡爾積 20 * 8 = 1605 + 2 = 7

多表查詢就是從這個笛卡爾積中選出所符合條件的結果

Oracle鏈接;

Equijoin :等值鏈接whereemp.deptno = dep.deptno;

Non-equijion:不等值鏈接where emp.deptno between 10and 20

Outer join:外連接

Self join:自連接

外連接:

按部門統計員工人數-à部門號、部門名稱、人數

Selectd.deptno,d.dname,count(e.empno)

From dept d,emp e

Where d.deptno = e.deptno(1)

Group by d.deptno,d.dname(如果某個部門沒有員工,這樣查不正確的)

外連接解決的問題:當條件不成立時候,仍然希望在結果中包含不成立的記錄

左外連接:== 左邊代表的表信息仍然包含在結果中

左外連接的表是在 == 的右邊

寫法(1)改爲 -à where e.deptno = d.deptno(+);

右外連接:與左外連接相反

自連接:核心是利用表的別名,將同一張表視爲多張表

查詢XX的老闆是YY

Selecte.ename||’的老闆是’||b.ename

Fromemp e,emp b

Wheree.mgr = b.empno;


層次查詢:

自連接查找大表的時候(1億行),笛卡爾積會很大,會嚴重影響性能,因此自連接不適合大表

層次查詢可以解決這個問題(就是樹操作,對樹進行遍歷)

層次查詢後面from只能有一張表,因爲不能有笛卡爾積

在層次查詢中不再是表和表做連接操作,而是對同一張表的前後兩次操作進行連接

上一層的員工就是下一層員工的老闆,要遍歷一棵樹就必須知道根root

Connect by prior empno = mgr start withmgr is null(總boss

或者 start with empno = 7566(從某一個管理人員開始)

Select level(僞列,層次123) ,empno,ename,mgr

From emp

Connect by prior empno = mgr

Start with mgr is null;

應用場景:中國-à江西à九江à都昌à街道


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章