Oracle筆記(一)

Oracle筆記系列這幾篇是來自一位老師的筆記,分享給大家放在簡書上,主要方便自己時常復習,還有學習Oracle的伙伴參考。(@來自邵永波老師整理分享)

最后找時間會寫一篇Oracle部分的總結


前言? ? oracle sql

第一章? Selecting Rows

第二章? Sorting & Limiting Selected Rows

第三章? Single Row Functions

第四章? Displaying Data from Multiple Tables

第五章? Group Function

第六章? Subqueries

第七章? Specifying Variables at Runtime

第八章? Overview of Data Modeling and Database Design

第九章? Creating Tables

第十章? Oracle Data Dictionary

第十一章 Manipulating Data(DML)

第十二章 Altering Tables and Constraints

第十三章 Creating Sequences

第十四章 Creating View

第十五章 Creating Indexes

第十六章 Controlling User Access

前言

1.一個認知

認知什么是oracle?

oracle:商業運用第一的關系型數據庫

實質:關系型數據庫

了解oracle數據庫發展歷史(文檔)

oracle8i? 9i? 10g? 11g? 12c不同字母代表的含義:

1998年9月,ORACLE公司正式發布ORACLE 8i。“i”代表Internet,這一版本中添加了大量為支持Internet而設計的特性;

2003年9月8日,ORACLE World大會上,“ORACLE 10g”發布,“g”代表“grid,網格”,這一版的最大的特性就是加入了網格計算的功能;

2013年6月26日,Oracle Database 12c版本正式發布, c是cloud,也就是代表云計算的意思。

2.二個概念

數據庫:數據存儲的倉庫

60年代興起,是計算機科學技術的一個重要分支。核心任務是管理數據,包括對數據分類、組織、編碼、存儲、檢索和維護。

到現在經歷了人工管理(1950之前)、文件系統(50年代后期到60年代中期)、數據庫系統(60年代后期到現在)三個階段。

關系型數據庫(RDBMS):基于關系模型來組織數據的數據庫,屬于第二代數據庫。

關系模型:用一個二維表,行(記錄)和列(字段)的形式來保存數據;關系模型里面的關系 主要反映到以后學習的主外鍵。

例如:

表名? ? ? s_dept部門

列(字段)? 部門編號id? 部門名稱name

行(記錄)? 1? ? ? ? ? 研發部

2 ? 市場部

3 ? 人事部

員工表s_emp? 記錄所有員工信息

id? name? dept_id salary? title

1? larry 1 ? 15000? ceo

2? tom? 1? ? ? 13000? 研發部經理

關系型數據庫的簡單理解是二維數據庫,類似Excel表格,有行有列。這種數據庫非高級,非性能最優,但應用最廣泛,因為容易理解使用。

數據庫系統發展歷史:

第一代:層次和網狀數據庫

第二代:關系型數據庫

第三代:對象型數據庫(理論階段,尚未大量應用)

具體信息可參閱 了解數據庫發展歷史(文檔)。

關系型數據庫優點:

容易理解,很貼近現實世界。

使用方便,SQL語句。(增刪改查)

容易維護,豐富的完整性大大降低了數據冗余和數據不一致的概率。

關系完整性規則:

實體完整性 主鍵值唯一存在

參照完整性 外鍵值為空或取其他表中主鍵值

用戶自定義完整性 符合應用場景中具體的約束條件

3.三個名詞

sql: 結構化的查詢語句,操作oracle數據庫的語言? 增刪改查?

select * from table_name;

sqlplus: oracle軟件自帶的可以輸入sql,且將sql執行結果顯示的終端的一個工具。

注意區分sql語句和sqlplus語句。

pl/sql: 程序化的sql語句,在sql語句的基礎上加入一定的邏輯操作,如if for...,使之成為一個sql塊,完成一定的功能。

4.四種對象

table:表格,由行和列組成,列又稱字段,每一行內容為表格的一條完整的數據。

view:? 視圖,一張表或者多張表的部分或者完整的映射,好比表格照鏡子,鏡子里面的虛像就是view。

除去常見的table和view兩種常用對象以外,oracle數據庫還支持如下四種對象:

sequence: 序列

index: 索引,提高數據的訪問效率

synonym: 同義詞,方便對象的操作

program unit:程序單元,pl/sql操作的對象

5.五種分類

sql的五大分類:

Data retrieval:數據查詢

select

DML:數據操縱語言(行級操作語言)

操作的是表格當中一條一條的數據

insert update delete

DDL:數據定義語言(表級操作語言)

操作的內容為表格(對象)

create alter drop truncate rename

transaction control:事務控制

commit rollback savepoint

DCL:權限控制語言

grant revoke

*************************************

數據庫安裝配置 準備:

1.安裝oracle數據庫

1.1 最好默認按照到C盤

1.2 安裝過程中有一步需要輸入一個密碼,建議使用oracle作為密碼,方便記憶

1.3 安裝完成之后,打開系統服務,查看服務是否已經正常啟動,具體情況參照文檔:oracle系統服務.txt

1.4 打開cmd,輸入sqlplus,然后回車查看是否能執行該命令

1.5 如果不能執行,則需要把安裝目錄里面的BIN里面配置到系統環境變了path中,然后重新打開一個cmd窗口即可

C:\oraclexe\app\oracle\product\10.2.0\server\BIN;

注意:oracle的卸載具體參照文檔

2.登錄oracle自帶的管理系統,新建一個屬于自己的賬號

oracle自帶管理系統登錄地址:

http://127.0.0.1:8080/apex/

參照文檔:oracle系統服務.txt

3.導入數據

用戶創建好之后,使用sqlplus命令登錄到oracle數據庫中,然后把之后要使用到的表及其數據導入到數據庫中.

參照文檔:導入數據.txt

4.了解導入的三張表以及相互關系

s_emp 員工表

s_dept 部門表

s_region 地區表

s_customer? 客戶表

5.之后登錄或者操作數據庫,就可以使用這個新創建的用戶了

====================================================================

第一章:select語句,數據查詢操作

1.使用select語句查詢某張表的所有數據內容

語法:

select *|{[distinct] col_name|expression [別名],...}

from tb_name;

注意:

語法中出現的中括號[],表示該部分可有可無;

*:表示所有列,僅作為測試和學習使用,在企業用語中不出現,因為效率低下且可讀性差;

col_name:列名,將需要查閱的數據字段列舉出來,可以查看多列值,列名之間用‘,’進行分割;

s_emp :員工信息表

s_dept:員工部門表

了解表結構: desc table_name

需求:查看s_dept表中的所有記錄

select *

from s_dept;

select id,name,region_id

from s_dept;

練習:查看s_dept表中的所有記錄的id和name

select id,name

from s_dept;

練習:查看所有員工的id,名字(last_name)和薪資(salary)

select id,last_name,salary

from s_emp;

SQL語句書寫注意事項:

SQL語言大小寫不敏感;

SQL可以寫在一行或多行;

關鍵字不能縮寫,也不能分行;

各子句一般分行寫;

使用縮進提高語句的可讀性。

2.select語句可以對指定的列的所有值進行算術運算

語法:

select col_name 運算符 數字

from tb_name;

需求:查看每個員工的員工id,名字和年薪。

select id,last_name,salary*12

from s_emp;

練習:查看每個員工的員工id,名字和月薪漲100以后的年薪

select id,last_name,(salary+100)*12

from s_emp;

注意:*? /? +? -

select語句永遠不對原始數據進行修改;

乘除的優先級高于加減;

優先級相同時,按照從左到右運算;

可以使用括號改變優先級。

3.給查詢的列起別名

語法:

select old_column [as] 別名

from tb_name;

使用列的別名,便于計算;別名中可以【使用雙引號】,以便于別名中包含空格或特殊的字符并區分大小寫。

需求:查看員工的員工id,名字和年薪,年薪列名為annual

select id,last_name,salary*12 as annual

from s_emp;

4.使用||可以使得多列的值或者列和特殊的字符串合并到一個列進行顯示

語法:

select col_name||'spe_char'||col_name

from tb_name

'spe_char':如果一個列的值要跟特殊的字符串連接顯示,使用該語法。

需求:查看員工的員工id,全名

select id,first_name||last_name

from s_emp;

練習:查看員工的員工id,全名和職位名稱,全名和職位名稱合并成一列顯示,且格式為:姓 名,職位名稱

select id,first_name||' '||last_name||','||title as name

from s_emp;

5.對null值得替換運算

nvl()函數

nvl(a,b)函數作用為: 如果a為空返回b,否則返回a;

語法:

select nvl(col_name,change_value)

from tb_name;

需求:查看所有員工的員工id,名字和提成,如果提成為空,顯示成0

select id,last_name,nvl(commission_pct,0) commission_pct

from s_emp;

注意:

空值是無效的,未指定的,未知的或不可預知的值;

空值不是空格,也不是0;

包含空值的表達式的值都為空值。

6.使用distinct關鍵詞,可以將顯示中重復的記錄(行)只顯示一條

語法:

select distinct col_name,col_name...

from tb_name;

注意1:distinct關鍵詞只能放在select關鍵詞后面

如:select id,distinct title

? ? from s_emp;

該語句語法錯!!!!!

注意2:如果distinct關鍵詞后面如果出現多列,表示多列聯合去重,即多列的值都相同的時候才會認為是重復的記錄。

test表:

id id2

1 2

1 3

2 4

3 4

3 4

select distinct id,id2

from test;

顯示結果為:

id id2

1 2

1 3

2 4

3 4

需求:查看所有員工的職位名稱和部門id,同職位同部門的只顯示一次

select distinct title,dept_id

from s_emp;

--補充內容--

字符串

字符串可以是select 列表中的一個字符、數字、日期;

日期和字符只能在單引號中出現;

每當返回一行時,字符串被輸出一次;

雙引號表示別名。

7.sqlplus命令

使用sqlplus登錄數據庫

sqlplus 輸入用戶名? 再輸入密碼

sqlplus 用戶名? 直接輸入密碼即可

sqlplus 用戶名/密碼 直接登錄

sqlplus "/as sysdba" 超級管理員登錄(很危險? 操作系統對應的用戶才可以登錄,在linux里面只有oracle用戶才可以登錄)

password 用戶名? 給用戶改密碼

show user 查看當前用戶

$cls 清屏

$其他cmd命令

sqlplus登錄之后,可以使用buff(緩存)來存儲/執行/修改要執行的sql語句

這里的buff有以下特點:

a.buff中只能存儲一條sql語句(但是這條sql語句可能有很多行)

b.每次放入新的sql語句,會把之前的覆蓋掉

c.每次執行sql語句,都會把這個sql語句放到buff里面

和buff相關的命令有:

list(l) 查看緩存中的sql語句

append(a) 在[定位]的那一行后面追加新的內容

in(i)? 在[定位]的那一行下面插入新的一行

change(c)? 替換[定位]的那一行中的某些字符串

c/老的字符串/新的字符串

del 刪除[定位]的那一行內容

n? 后面加內容可以重寫這一行

!? 后面接終端命令 !clear:清屏(linux命令)

$ windows中使用$符號 例如:$cls

/? 執行緩存sql命令

clear buffer:清空當前緩存的命令

save 路徑 [replace] buff中的sql語句保存在指定文件中

get? test.sql? 把test.sql中的內容在加載到buff中,但是沒有運行

start test.sql? 把test.sql中的內容在加載到buff中并且執行

@test.sql? ? ? 把test.sql中的內容在加載到buff中并且執行

edit file_name? 使用系統默認編輯器去編輯文件

desc describe

ed edit

c change

col column

for format

spool file_name 將接下來的sql語句以及sql的運行結果保存到文件中

sql1

result1

sql2

result2

...

spool off? 關閉spool功能

exit:退出(sqlplus退出)

8.select id,last_name,first_name, salary, dept_id

? from s_emp

? Where rownum <=10;

? 結果不好看,通過column使我們的顯示界面好看。

COLUMN last_name FORMAT a15

可以簡寫為:

col last_name for a15

注意:

column大小寫不區分,另外只能設置字符串類型格式;

column 沒有改變數據表里數據,它只是改變顯示的方式;

column不是sql關鍵字,而是sqlplus命令。

COLUMN last_name HEADING 'Employee|Name' FORMAT A15

給last_name取別名為Employee|Name , 豎杠代表換行;

A15表示十五個字節長,一短橫杠就是一個字節長。

COLUMN salary JUSTIFY LEFT FORMAT $99,999.00

salary JUSTIFY LEFT : 僅僅改變列名顯示為左齊;

FORMAT $99,999.00: 控制顯示格式為前面加 $ 符, “,”為分隔符, 0或9代表數字(通配符),0表示替換對齊數值,位數不足會補足,可以混合使用。

COLUMN start_date FORMAT A15 NULL 'Not hired'

如果start_date值為空的話,顯示為’Not hired’;

Format后不能直接跟null, 要先a10或a15;

NULL 'Not hired'和nvl類似。

column columName 顯示所有對列格式的設置情況(可以顯示該列的格式設置,這里的列并不特定于某個表)

例如:

column last_name 顯示對last_name列顯示設置的情況

column last_name clear 刪除對last_name列格式設置的情況

clear column 清除所有column的格式設置

注意:

數字列不能設置col a15格式

例如:col salary format a15

1234? column 99.99? -- > ######

格式設置不對,出錯不能顯示,只是顯示####

sql語句和sqlplus命令區別

sql是一種語言

ANSI標準

關鍵字不能縮寫

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

sqlplus是一種環境

Oracle的特性之一

關鍵字可以縮寫

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

集中運行

第二章:排序和限制查詢

*****排序************

1.排序:所謂排序,就是根據某個字段的值按照升序或者降序的情況將記錄查詢出來

語法:

select col_name,...

from tb_name

order by col_name [asc|desc],...

注意:

a. 排序使用order by字句

b. 該子句只對查詢記錄顯示調整,并不改變查詢結果,所以執行權最低,即最后執行

2.排序關鍵詞:

asc:升序(默認,默認的意思是不加關鍵詞的時候默認為生序排序)

desc:降序

3.如果有多個列排序,后面的列排序的前提是前面的列排好序以后有重復(相同)的值

例如:

id id2

1 2

2 3

3 4

4 1

4 2

語句:

select id,id2

from test

order by id [asc],id2 desc;

結果:

id id2

1 2

2 3

3 4

4 2

4 1

注意:

先排第一列,如果第一列有重復的值再排第二列,以此類推

需求:查看員工的id,名字和薪資,按照薪資的升序排序顯示,如果薪資相同則按照id降序排列。

4.order by 后面還可以跟數字,表示使用select后面的第幾個列進行排序

例如:

//使用last_name列進行排序

select last_name,salary

from s_emp

order by 1;

//使用salary列進行排序

select last_name,salary

from s_emp

order by 2 desc;

******限制查詢**********************

1.限制查詢,即指定查詢條件進行查詢

語法:

select col_name,...

from tb_name

where col_name 比較操作表達式

邏輯操作符(and|or)

? ? ? col_name 比較操作表達式

...

注意:

1).限制查詢條件,使用where子句

2).條件可以多個,使用邏輯操作符和()進行條件的邏輯整合

3).where子句的優先級別最高

4).比較操作表達式由操作符和值組成

2.常見的操作符之 邏輯比較操作符

=? >? <? >=? <=

不等于:三個都表示不等于的意思(經常用的是!=)

!=? <>? ^=

需求:查看員工工資小于1000的員工id和名字

select id,last_name,salary

from s_emp

where salary < 1000;

注意:

字符和日期要包含在單引號內

字符大小寫敏感,日期格式敏感;

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

修改日期格式:

select * from v$nls_parameters; //動態性能視圖,數據字典

alter session|system set NLS_DATE_FORMAT='yyyy-mm-dd';

? ? ? 當前? ? 所有

select [distinct] 字段1 as 別名,表達式

from 表

where ><>=<=!=? <>? ^=

order by 字段 asc|desc,字段 [asc];

||? concat();

3.sql比較操作符

[NOT] BETWEEN ... AND ...

? [NOT] IN(list)

? [NOT] LIKE?

? IS [NOT] NULL

between x and y:在什么范圍之內 [x,y]

需求:查看員工工資在700 到 1500之間的員工id,和名字

select id,last_name,salary

from s_emp

where salary between 700 and 1500;

也可以在日期列上使用between and操作,但是要看當前session會話的語言環境來決定使用中文格式的日期還是英文格式的日期

alter session set nls_language='simplified chinese';

如果是中文的語言環境:

查詢在90年3月8號到91年2月9號之間入職的員工信息

select id,last_name,start_date

from s_emp

where start_date between '08-3月-90' and '09-2月-91';

alter session set nls_language=english;

如果是英文的語言環境:

查詢在90年3月8號到91年2月9號之間入職的員工信息

select id,last_name,start_date

from s_emp

where start_date between '08-MAR-90' and '09-FEB-91';

4.in(list)

在一個列表中篩選

需求:查看員工號1,3,5,7,9員工的工資

select id,last_name,salary

from s_emp

where id in (1,3,5,7,9);

需求:查看是在'08-3月-90'或者'09-2月-91'入職的員工信息

select id,last_name,start_date

from s_emp

where start_date in ('08-3月-90','09-2月-91');

需求:查看名字為Ngao或者Smith的員工信息

select id,last_name,salary

from s_emp

where last_name in ('Ngao','Smith');

5.like:模糊查詢

即值不是精確的值的時候使用

通配符,即可以代替任何內容的符號

% :通配0到多個字符? ? ?

_ : 當且僅當通配一個字符?

轉義字符:

默認為\,可以指定 指定的時候用escape? 符號指明即可,轉義字符只能轉義后面的一個字符

也可以使用其他字符作為轉義字符 +

'%+_%' escape '+';

需求:查看員工名字以C字母開頭的員工的id,工資。

select id,last_name,salary

from s_emp

where last_name like 'C%';

練習:查看員工名字長度不小于5,且第四個字母為n的員工id和工資

select id,last_name,salary

from s_emp

where last_name like '___n_%';

需求:查看員工名字中包換一個_的員工id和工資

注意:_是一個特殊字符,所以要轉義

select id,last_name,salary

from s_emp

where last_name like '%\_%' escape '\';

6.is null

對null值操作特定義的操作符,不能使用=

需求:查看員工提成為空的員工的id和名字

select id,last_name,commission_pct

from s_emp

where commission_pct is null;

7.邏輯操作符

當條件有多個的時候使用

and:且邏輯

or: 或邏輯

注意:and優先級比or優先級要高

not:非邏輯?

? NOT BETWEEN AND

?NOT IN

?NOT LIKE

? IS NOT NULL

需求:查看員工部門id為41且職位名稱為Stock Clerk(存庫管理員)的員工id和名字

select id,last_name,dept_id,title

from s_emp

where dept_id = 41

and

title = 'Stock Clerk';

練習:查看(員工部門為41) 或者 (44號部門 且工資大于1000的)員工信息

select id,salary,dept_id

from s_emp

where dept_id = 41

or dept_id = 44

and salary>1000;

查看(員工部門為41或44) 且(工資大于1000的)員工信息

select id,salary,dept_id

from s_emp

where (dept_id = 41

or dept_id = 44)

and salary > 1000;

需求:查看員工提成不為空的員工信息

select id,last_name,commission_pct

from s_emp

where commission_pct is not null;

需求:查看員工名字不是以C字母開頭的員工信息。

select id,last_name,salary

from s_emp

where last_name not like 'C%';

*****單值函數*****************

第三章:單值(單列、單行)函數

1.函數分為兩大類

單值函數

a.字符函數

b.日期函數

c.轉換函數

d.數字函數

分組函數(后面章節學習)

基礎知識準備:啞表、偽表dual

dual是一個虛擬表,用來構成select的語法規則,oracle保證dual里面永遠只有一條記錄。數據庫中所有用戶都有權限使用;

只是為了滿足語法要求。

例如:

顯示1+1的結果,可以看出,dual很多時候是為了構成select的標準語法;

select 1+1 from dual;


2.字符函數

LOWER Converts to lowercase

UPPER Converts to uppercase

INITCAP Converts to initial capitalization

CONCAT Concatenates values

SUBSTR Returns substring

LENGTH Returns number of characters

NVL Converts a null value

以上這些函數可以操作表中的列,也可以操作普通字符串。

1).lower 把字符轉為小寫

例如:把'HELLO'轉換為小寫

select lower('HELLO')

from dual;


例如:把s_emp表中的last_name列的值轉換為小寫

select lower(last_name)

from s_emp;

2).upper 把字符轉換為大寫

例如:把'world'轉換為大寫

select upper('world')

from dual;

例如:把s_emp表中的last_name列的值轉換為大寫

select upper(last_name)

from s_emp;



例如:查詢s_emp表中名字為Ngao的人信息

按照以下操作是查不到的:

select last_name,salary,dept_id

from s_emp

where last_name='NGAO';

修改后就可以查詢到了:

select last_name,salary,dept_id

from s_emp

where upper(last_name)='NGAO';

3).initcap 把字符串首字母轉換為大寫

例如:把'hELLO'轉換為首字母大寫,其余字母小寫

select initcap('hELLO')

from dual;


4).concat 把倆個字符串連接在一起(類似之前的||的作用)

例如:把'hello'和'world'倆個字符串連接到一起,并且起個別名為msg

select concat('hello','world') msg

? ? ? ? from dual;


例如:把first_name和last_name倆個列的值連接到一起

select concat(first_name,last_name) as name

? ? ? ? from s_emp;


5).substr(操作項,start,len) 截取字符串

例如:截取'hello'字符串,從第2個字符開始(包含第二個字符),截取后面連續的3個字符

select substr('hello',2,3)

from dual;

注意:不按照下標進行。

6)length 獲得字符串長度

例如:獲得'world'字符串的長度

select length('world')

from dual;

例如:獲得s_emp表中last_name列的每個值的字符長度

select length(last_name)

from s_emp;

7).nvl(操作項,替換值) 替換列中為null的值

在前面的章節已經使用過了

select last_name,nvl(commission_pct,0)

from s_emp;

3.數字函數

ROUND Rounds value to specified decimal

TRUNC Truncates value to specified decimal

MOD Returns remainder of division?

1)round 四舍五入

round(arg1,arg2)

第一個參數表示要進行四舍五入操作的數字

第二個參數表示保留到哪一位

例如:

保留到小數點后面2位

select round(45.926,2)

from dual;

保留到個位 (個十百千萬...)

select round(45.923,0)

from dual;

保留到十位 (個十百千萬...)

select round(45.923,-1)

from dual;

2).trunc 截取到某一位

trunc(arg1,arg2)

和round的用法一樣,但是trunc只舍去不進位

例如:

截取到小數點后面2位

select trunc(45.929,2)

from dual;

截取到個位 (個十百千萬...)

select trunc(45.923,0)

from dual;

截取到十位 (個十百千萬...)

select trunc(45.923,-1)

from dual;

3).mod 取余

mod(arg1,arg2)

第一個參數表示要進行取余操作的數字

第二個參數表示參數1和誰取余

例如:

把10和3進行取余 (10除以3然后獲取余數)

select mod(10,3)

from dual;

4.日期函數

MONTHS_BETWEEN? Number of months between two dates

ADD_MONTHS ? Add calendar months to date

NEXT_DAY Next day of the date specified

LAST_DAY ? ? Last day of the month

ROUND ? ? ? ? Round to date at midnight

TRUNC ? ? ? ? Remove time portion? from date

? 1).sysdate關鍵字

表示系統的當前時間

例如:

顯示當前系統時間

select sysdate from dual;

注意:sysdate進行加減操作的時候,【單位是天】

例如:

顯示時間:明天的這個時候

select sysdate+1 from dual;

例如:

顯示時間:昨天的這個時候

select sysdate-1 from dual;

例如:

顯示時間:1小時之后的這個日期

select sysdate+1/24 from dual;

2).months_between

倆個日期之間相差多少個月【單位是月】

例如:

30天之后和現在相差多少個月

select months_between(sysdate+30,sysdate)

from dual;

【結果可以是小數】

select months_between(sysdate+10,sysdate)

from dual;

3).add_months? 返回一個日期數據:表示一個時間點,往后推x月的日期

例如:

'01-2月-2016'往后推2個月

select add_months('01-2月-2016',2)

from dual;

例如:

當前時間往前推4個月

select add_months(sysdate,-4)

? ? from dual;

注意:這個數字也可以是負數,表示往前推x月

4).next_day

返回日期:表示下一個星期幾在哪一天

例如:

離當前時間最近的下一個星期5是哪一個天

select next_day(sysdate,'星期五')

from dual;

注意: 如果要使用'FRIDAY',那么需要把當前會話的語言環境修改為英文

5).last_day

返回日期:表示指定月份的最后一天

例如:

當前日期所在月份的最后一天(月底)

select last_day(sysdate)

from dual;

6).round?

對日期進四舍五入,返回操作后的日期數據

例如:

把當前日期四舍五入到月

select round(sysdate,'MONTH')

from dual;

測試: 15號16號分別是舍棄還是進位

結論: 15不進,16進

把當前日期四舍五入到年(6月舍棄,7月進位)

select round(sysdate,'YEAR')

from dual;

//使用默認的日期格式進行四舍五入會出錯

//因為數字函數也有一個round,倆個ronnd函數有沖突

select round('01-2月-16','MONTH')

from dual;

7).trunc?

對日期進行截取 和round類似,但是只舍棄不進位

5.類型轉換函數

TO_CHAR

converts a number or date string to a character string.

? TO_NUMBER

converts a character string containing digits to a number.

?? TO_DATE

converts a character string of a date to a date value.

1).to_char 把日期轉換為字符

例如:把當前日期按照指定格式轉換為字符串

select to_char(sysdate,'yyyy-mm-DD')

from dual;

日期格式:

? yyyy:四位數的年份

? rrrr:四位數的年份

? yy:兩位數的年份

? rr:兩位數的年份? yyyy-mm-DD hh:mi:ss

? mm:兩位數的月份(數字)

? D:一周的星期幾

? DD:一月的第幾天

? DDD :一年的第幾天

? YEAR:英文的年份

? MONTH:英文全稱的月份

? mon:英文簡寫的月份

? ddsp:英文的第幾天(一個月的)

? ddspth:英文序列數的第幾天(一個月的)

? DAY:全英文的星期

? DY:簡寫的英文星期

? hh[12|24]:小時? 默認12進制

? mi:分鐘

? ss:秒

? am: 上下午

例如:

測試常見的一些日期數據轉換為字符串的格式

select to_char(sysdate,'yyyy MM D DD DDD YEAR MONTH ddsp ddspth DAY DY')

from dual;

select to_char(sysdate,'dd-mm-yy')

from dual;

select to_char(sysdate,'yy-mm-dd')

from dual;

select to_char(sysdate+5/24,'dd-mm-yy HH24:MI:SS AM')

from dual;

千年蟲問題:

在早期的計算機的程序中規定了的年份僅用兩位數來表示。也就是說,假如是1971年,在計算機里就會被表示為71,但是到了2000年的時候這個情況就出現了問題,計算機就會將其年份表示為00。這樣的話計算機內部對年份的計算就會出現問題。這個事情當時被稱為千年蟲

數據庫中表示日期中年份的有倆種: yy和rr

之前一直使用的時候yy格式,后來才有的rr格式

yy表示使用一個倆位數表示當前年份:

1990 ---yy數據庫格式---> 90

1968 ---yy數據庫格式---> 68

1979 ---yy數據庫格式---> 79

rr格式表示: 另外參照圖片:rr日期格式規則.png

如果日期中的年份采用的格式為rr,并且只提供了最后2位年份,那么年份中的前兩位數字就由兩部分共同確定:提供年份的兩位數字(指定年),數據庫服務器上當前日期中年份的后2位數字(當年)。確定指定年所在世紀的規則如下:

規則1

如果指定年在00~49之間,并且當前年份在00~49之間,那么指定年的世紀就與當前年份的世紀相同。因此,指定年的前兩位數字就等于當前年份的前兩位數字。例如,如果指定年為15,而當前年份為2007,那么指定年就是2015。

規則2

如果指定年在50~99之間,并且當前年份在00~49之間,那么指定年的世紀就等于當前年份的世紀減去1。因此,指定年的前兩位數字等于當前年份的前兩位數字減去1。例如,如果指定年為75,而當前年份為2007,那么指定年就是1975。

規則3

如果指定年在00~49之間,并且當前年份在50~99之間,那么指定年的世紀就等于當前年份的世紀加上1。因此,指定年的前兩位數字等于當前年份的前兩位數字加上1。例如,如果指定年為15,而當前年份為2075,那么指定年就是2115。

規則4

如果指定年在50~99之間,并且當前年份在50~99之間,那么指定年的世紀就與當前年份的世紀相同。因此,指定年的前兩位數字就等于當前年份的前兩位數字。例如,如果指定年為55,而當前年份為2075,那么指定年就是2055。

注意:rr格式并沒有完全的解決倆位數年份保存的問題,只是將問題往后推了50年。

2).to_char 把數字轉換為字符

格式: to_char(number,'fmt')

0:表示強制顯示小數點后精度

9: 表示顯示數字

.: 表示小數點

,:千位標識符

L: 表示系統本地的貨幣符號

$: 美元貨幣

例如:

? ? select to_char(salary,'$999,999.00')

from s_emp;

【fm】表示【去除】結果顯示中的【開始的空格】

select to_char(salary,'fm$999,999.00')

from s_emp;

L表示系統本地的貨幣符號

select to_char(salary,'fmL999,999.00')

from s_emp;

3).to_number 把字符轉換為數字

例如:

select to_number('0100')

from dual;

//這個寫法是錯的 abc不能轉換為數字

select to_number('abc')

from dual;

4).to_date 把字符轉換為日期

例如:

select to_date('10-12-2016','dd-mm-yyyy')

from dual;

select to_date('25-5月-95','dd-month-yy')

from dual;

select to_date('95/5月/25','yy/month/dd')

from dual;

//session語言環境設置為英文下面可以運行

select to_date('25-MAY-95','dd-MONTH-yy')

from dual;

5).總結

oracle數據庫中表示一個日期數據的方式有:

? a.使用sysdate

? b.使用oracle默認的日期格式 例如:'25-MAY-95'

? c.使用日期函數ADD_MONTHS/NEXT_DAY/LAST_DAY/ROUND/TRUNC

? d.使用轉換函數to_date

6).函數之間的嵌套

? 格式:F3(F2(F1(arg0,arg1),arg2),arg3)

? 例如:

? 先把'hello'和'world'連接起來,再轉換為字母大寫然后再從第4個字符開始,連著截取4個字符

? select substr(upper(concat('hello','world')),4,4)

? from dual;

*****重點**********

第四章:多表查詢

多表查詢,又稱表聯合查詢,即一條sql語句涉及到的表有多張,數據通過特定的連接進行聯合顯示.

1.笛卡爾積

在數學中,將兩個集合X和Y任意組合,得到的結果叫做笛卡尓積(Cartesian product),又稱直積,表示為X × Y。

例如集合A={a, b},集合B={0, 1, 2},則兩個集合的笛卡爾積為{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。

在數據庫中,如果直接查詢倆張表,那么其查詢結果就會產生笛卡爾積。

例如:

select last_name,name

from s_emp,s_dept;

2.連接查詢

為了在多表查詢中避免笛卡爾積的產生,我們可以使用連接查詢來解決這個問題.

連接查詢分為:

a.等值連接

b.不等值連接

c.外連接

左外連接

右外連接

全連接

d.自連接

3.等值連接

利用一張表中某列的值和另一張表中某列的值相等的關系,把倆張表連接起來。

例如:查詢員工的名字、部門編號、部門名字

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id=s_dept.id;

為了表述的更加清楚,可以給每張表起別名

select se.last_name,se.dept_id,sd.id,sd.name

from s_emp se,s_dept sd

where se.dept_id=sd.id;

查詢部門的id,名稱以及所在區域的名稱;

select sd.id,sd.name,sr.id,sr.name

from s_dept sd,s_region sr

where sd.region_id=sr.id;

select se.id,se.last_name,sd.id,sd.name,sd.region_id,sr.name

from s_emp se,s_dept sd,s_region sr

where se.dept_id = sd.id

and sr.id = sd.region_id;

4.不等值連接(連接兩張表,但并非使用等號實現)

假設數據庫中還有一張工資等級表:salgrade

工資等級表s_grade:

gradeName 列表示等級名稱

losal 列表示這個級別的最低工資數

hisal? ? 列表示這個級別的最高工資數

create table s_grade(

id number(7) primary key,

gradeName varchar2(30) not null,

losal number(7),

hisal number(7)

);

insert into s_grade values(1,'初級程序員',700,1200);

insert into s_grade values(2,'中級程序員',1201,2000);

insert into s_grade values(3,'高級程序員',2001,3000);

commit;

//刪除表

drop table s_grade;

表中的數據類似于下面內容:

表s_grade

id? gradeName losal hisal

1? 初級程序員? 700? 1200

2? 中級程序員? 1201? 2000

3? 高級程序員? 2001? 3000

例如:

查詢出員工的名字、職位、工資、工資等級名稱

SELECT? e.last_name, e.title, e.salary, s.gradeName

FROM? ? s_emp e, s_grade s

WHERE? e.salary BETWEEN s.losal AND s.hisal;

5.外連接

外連接分為:左外連接 右外連接 全連接

先分別在倆s_emp和s_dept表中插入新的數據

特點:新員工tom不在任何部門,新增部門st下面沒有任何員工

insert into s_emp(id,last_name) values(26,'tom');

insert into s_dept(id,name) values(60,'st');

commit;

等測試完以后可以通過下面sql語句刪除上述插入的數據:

delete from s_emp where id=26;

delete from s_dept where id=60;

commit;

這個時候再使用等值連接的話,查詢出來的數據就會少,因為新增的員工tom和部門表中的數據連接不上,當然新增的部門st也和員工表中的數據連接不上.那么這倆條數據都是在等值連接中查詢不出來.

6.左外連接

使用左外連接可以解決上述問題,在等值連接的基礎上,額外顯示左表中多出來的數據。

例如:

【查詢所有員工 以及對應的部門的名字】,沒有部門的員工也要顯示出來

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id=s_dept.id(+);

格式固定,在右邊表條件加上(+)即可。

或者 倆者是等價的

select last_name,dept_id,name

from s_emp left outer join s_dept

on s_emp.dept_id=s_dept.id;

格式固定,from 左表 left [outer] join 右表 on 連接條件。

注意:outer可以省去不寫

7.右外連接

在等值連接的基礎上,額外顯示右表中多余的信息【全部顯示右表信息】。

例如:

查詢所有員工 以及對應的部門的名字,沒有任何員工的部門也要顯示出來

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id(+)=s_dept.id;

select last_name,dept_id,name

from s_emp right outer join s_dept

on s_emp.dept_id=s_dept.id;

注意:outer可以省去不寫

8.全連接

全連接可以將兩個表中額外多余的數據都顯示出來。

例如:

查詢所有員工 以及對應的部門的名字,沒有任何員工的部門也要顯示出來,沒有部門的員工也要顯示出來

select last_name,dept_id,name

from s_emp full outer join s_dept

on s_emp.dept_id=s_dept.id;

注意:outer可以省去不寫

9.自連接

兩張相同的表,進行連接

例如:

查詢每個員工的名字以及員工對應的管理者的名字

select s1.last_name,s2.last_name manager_name

from s_emp s1,s_emp s2

where s1.manager_id = s2.id;

s_emp s_emp

1 zs 2 1 zs 2

2 ls? 3 2 ls 3

3 ww? 3 ww

10.對查詢結果集(ResultSet rs)的操作

結果集: sql語句查詢得到的結果。

如果有倆條sql語句,每一條sql都可以查詢出一個結果,這個被稱之為結果集。那么我們可以使用下面的關鍵字對倆個結果集進行操作。

union 獲得倆個結果集的并集

union all 把倆個結果集 合在一起顯示出來

minus? ? 第一個結果集除去第二個結果集和它相同的部分

intersect 獲得倆個結果集的交集

注意:前提條件 倆個結果集中【查詢的列】要完全一致

1).union? 獲得倆個結果集的【并集】

(兩個結果集公共部分+左表額外+右表額外)

例如:

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id=s_dept.id(+)

union

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id(+)=s_dept.id;

2).union all? 把倆個結果集 合在一起顯示出來

例如:

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id=s_dept.id(+)

union all

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id(+)=s_dept.id;

3).minus? 第一個結果集除去第二個結果集和它相同的部分

例如:

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id=s_dept.id(+)

minus

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id(+)=s_dept.id;

對比倆種情況的結果

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id(+)=s_dept.id

minus

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id=s_dept.id(+);

4).intersect? 求倆個結果集的【交集】(公共部分)

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id=s_dept.id(+)

intersect

select last_name,dept_id,name

from s_emp,s_dept

where s_emp.dept_id(+)=s_dept.id;

11.oracle中的偽列 rownum

偽列rownum,就像表中的列一樣,但是在表中并不存儲。偽列【只能查詢】,不能進行增刪改操作。它會根據返回的結果為每一條數據生成一個【序列化】的數字。

rownum是oracle特有的。

rownum 所能作的操作有以下三種:

1).rownum 能等于1

如果讓其等于其他數 則查不到數據

例如:

select rownum,id,last_name

from s_emp

where rownum=1;

2).rownum 能大于0

如果讓其大于其他數 則查不到數據

rownum>=1也是可以的

例如:

select id,last_name

from s_emp

where rownum>=1;

3).rownum 可以<=任何數

例如:

select id,last_name

from s_emp

where rownum<=7

實際應用:

學完子查詢后,可以利用偽列進行分頁顯示。

select *

from (

select rownum r, id,last_name

from s_emp

where rownum <= 10

order by id desc

)

where r > 5;

注意: 偽列的次序是在排序之前就已經確定的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • ORACLE自學教程 --create tabletestone ( id number, --序號usernam...
    落葉寂聊閱讀 1,121評論 0 0
  • 1.簡介 數據存儲有哪些方式?電子表格,紙質文件,數據庫。 那么究竟什么是關系型數據庫? 目前對數據庫的分類主要是...
    喬震閱讀 1,777評論 0 2
  • 在看《人民的名義》這部電視劇,在看的過程中,真的是驚訝不斷,也在不斷地思考一些事情。這部前段時間火的不行的電視劇,...
    今天安好閱讀 358評論 0 1
  • 剛剛看到一個故事分享給大家 “媽媽,明天就是星期一了,我好討厭星期一啊。”女兒抱怨的說。 “哦?為什么呢?”媽媽問...
    丁昕家庭教育指導閱讀 308評論 0 0
  • 我仍然清晰地記得那天的晚上,大家陸續下課擁抱道別一一離開,梅子來到我們的面前,毫不掩飾自己的脆弱與起伏的情感,和我...
    leejayce閱讀 691評論 0 2