⑴ oracle的執行計劃中表的鏈接方式有幾種分別適用什麼情況
在日常基於資料庫應用的開發過程中,我們經常需要對多個表或者數據源進行關聯查詢而得出我們需要的結果集。那麼Oracle到底存在著哪幾種連接方式?優化器內部又是怎樣處理這些連接的?哪種連接方式又是適合哪種查詢需求的?只有對這些問題有了清晰的理解後,我們才能針對特定的查詢需求選擇合適的連接方式,開發出健壯的資料庫應用程序。選擇合適的表連接方法對sql語句運行的性能有著至關重要的影響。下面我們就Oracle常用的一些連接方法及適用情景做一個簡單的介紹。
3.1 嵌套循環連接(nested loop)
嵌套循環連接的工作方式是這樣的:
1、 Oracle首先選擇一張表作為連接的驅動表,這張表也稱為外部表(Outer Table)。由驅動表進行驅動連接的表或數據源稱為內部表(Inner Table)。
2、 提取驅動表中符合條件的記錄,與被驅動表的連接列進行關聯查詢符合條件的記錄。在這個過程中,Oracle首先提取驅動表中符合條件的第一條記錄,再與內部表的連接列進行關聯查詢相應的記錄行。在關聯查詢的過程中,Oracle會持續提取驅動表中其他符合條件的記錄與內部表關聯查詢。這兩個過程是並行進行的,因此嵌套循環連接返回前幾條記錄的速度是非常快的。在這里需要說明的是,由於Oracle最小的IO單位為單個數據塊,因此在這個過程中Oracle會首先提取驅動表中符合條件的單個數據塊中的所有行,再與內部表進行關聯連接查詢的,然後提取下一個數據塊中的記錄持續地循環連接下去。當然,如果單行記錄跨越多個數據塊的話,就是一次單條記錄進行關聯查詢的。
3、 嵌套循環連接的過程如下所示:
Nested loop
Outer loop
Inner loop
我們可以看出這裡面存在著兩個循環,一個是外部循環,提取驅動表中符合條件的每條記錄。另外一個是內部循環,根據外循環中提取的每條記錄對內部表進行連接查詢相應的記錄。由於這兩個循環是嵌套進行的,故此種連接方法稱為嵌套循環連接。
嵌套循環連接適用於查詢的選擇性強、約束性高並且僅返回小部分記錄的結果集。通常要求驅動表的記錄(符合條件的記錄,通常通過高效的索引訪問)較少,且被驅動表連接列有唯一索引或者選擇性強的非唯一索引時,嵌套循環連接的效率是比較高的。
嵌套循環連接驅動表的選擇也是連接中需要著重注意的一點,有一個常見的誤區是驅動表要選擇小表,其實這是不對的。假如有兩張表A、B關聯查詢,A表有1000000條記錄,B表有10000條記錄,但是A表過濾出來的記錄只有10條,這時候顯然用A表當做驅動表是比較合適的。因此驅動表是由過濾條件限制返回記錄最少的那張表,而不是根據表的大小來選擇的。
在外連接查詢中,如果走嵌套循環連接的話,那麼驅動表必然是沒有符合條件關聯的那張表,也就是後面不加(+)的那張表。這是由於外連接需要提取可能另一張表沒符合條件的記錄,因此驅動表需要是那張我們要返回所有符合條件記錄的表。比如下面這個查詢,
嵌套循環連接返回前幾行的記錄是非常快的,這是因為使用了嵌套循環後,不需要等到全部循環結束再返回結果集,而是不斷地將查詢出來的結果集返回。在這種情況下,終端用戶將會快速地得到返回的首批記錄,且同時等待Oracle內部處理其他記錄並返回。如果查詢的驅動表的記錄數非常多,或者被驅動表的連接列上無索引或索引不是高度可選的情況,嵌套循環連接的效率是非常低的
-- 刪除原表
drop table t1;
-- 建立測試表
create table t1(
f1 varchar2(10),
f2 varchar2(1000)
)
tablespace CTL
pctfree 98;
-- 填充測試內容
insert into t1(f1,f2)
select rownum, lpad(rownum,700,'0')
from dba_tables a, dba_tab_cols b
where a.owner = b.owner
and rownum < 10000;
commit;
-- 檢查測試內容格式
select sys.dbms_rowid.rowid_block_number(rowid), f1, f2 from t1;
-- 每條記錄都存儲在單獨的數據塊中
select count( distinct sys.dbms_rowid.rowid_block_number(rowid)) from t1;
/*
用同樣的方式建立表t2
*/
-- 刪除原表
drop table t2;
-- 建立測試表
create table t2(
f1 varchar2(10),
f2 varchar2(1000)
)
tablespace CTL
pctfree 98;
-- 填充測試內容
insert into t2(f1,f2)
select rownum * 10, lpad(rownum * 10,700,'0')
from dba_tables a, dba_tab_cols b
where a.owner = b.owner
and rownum < 1000;
commit;
-- 檢查測試內容格式
select sys.dbms_rowid.rowid_block_number(rowid), f1, f2 from t2;
-- 每條記錄都存儲在單獨的數據塊中
select count( distinct sys.dbms_rowid.rowid_block_number(rowid)) from t2;
create index ind_t1_f1 on t1(f1);
create index ind_t2_f1 on t2(f1);
--首先我們來看使用nested loop關聯方式, 不同表作為驅動時的情況.
1, 表t2作為驅動表
select /*+ ordered use_nl(t1 , t2)*/
t1.f1, t2.f1
from ctl.t2 t2,ctl.t1 t1
where t1.f1 = t2.f1
and t1.f1 < 1000;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=84 Card=4 Bytes=56)
1 0 NESTED LOOPS (Cost=84 Card=4 Bytes=56)
2 1 TABLE ACCESS (FULL) OF 'T2' (Cost=2 Card=82 Bytes=574)
3 1 INDEX (RANGE SCAN) OF 'IND_T1_F1' (NON-UNIQUE) (Cost=1 C
ard=1 Bytes=7)
Cost = outer access cost + (inner access cost * outer cardinality)
Cost = 2 + 1 * 82 = 84;
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2020 consistent gets
23 physical reads
0 redo size
2650 bytes sent via SQL*Net to client
721 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
99 rows processed
2, t1作為驅動表
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=4 Bytes=56)
1 0 NESTED LOOPS (Cost=6 Card=4 Bytes=56)
2 1 TABLE ACCESS (FULL) OF 'T1' (Cost=2 Card=4 Bytes=28)
3 1 INDEX (RANGE SCAN) OF 'IND_T2_F1' (NON-UNIQUE) (Cost=1 C
ard=1 Bytes=7)
Cost = outer access cost + (inner access cost * outer cardinality)
Cost = 2 + 1 * 4 = 84;
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
11123 consistent gets
3 physical reads
0 redo size
2650 bytes sent via SQL*Net to client
721 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
99 rows processed
3.2, 哈希連接(hash join)
哈希連接分為兩個階段,如下。
1、 構建階段:優化器首先選擇一張小表做為驅動表,運用哈希函數對連接列進行計算產生一張哈希表。通常這個步驟是在內存(hash_area_size)裡面進行的,因此運算很快。
2、 探測階段:優化器對被驅動表的連接列運用同樣的哈希函數計算得到的結果與前面形成的哈希表進行探測返回符合條件的記錄。這個階段中如果被驅動表的連接列的值沒有與驅動表連接列的值相等的話,那麼這些記錄將會被丟棄而不進行探測
哈希連接比較適用於返回大數據量結果集的連接。
使用哈希連接必須是在CBO模式下,參數hash_join_enabled設置為true,
哈希連接只適用於等值連接。從Oracle9i開始,哈希連接由於其良好的性能漸漸取代了原來的排序合並連接。
SQL> select /*+ ordered use_hash(t1 , t2) */
t1.f1, t2.f1
from ctl.t1 t1,ctl.t2 t2
where t1.f1 = t2.f1 2 3 4 ;
999 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=82 Bytes=1148
)
1 0 HASH JOIN (Cost=5 Card=82 Bytes=1148)
2 1 TABLE ACCESS (FULL) OF 'T1' (Cost=2 Card=82 Bytes=574)
3 1 TABLE ACCESS (FULL) OF 'T2' (Cost=2 Card=82 Bytes=574)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
11113 consistent gets
0 physical reads
0 redo size
23590 bytes sent via SQL*Net to client
1381 bytes received via SQL*Net from client
68 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
999 rows processed
3.3, 排序合並連接(merge join)
排序合並連接的方法非常簡單。在排序合並連接中是沒有驅動表的概念的,兩個互相連接的表按連接列的值先排序,排序完後形成的結果集再互相進行合並連接提取符合條件的記錄。相比嵌套循環連接,排序合並連接比較適用於返回大數據量的結果。
排序合並連接在數據表預先排序好的情況下效率是非常高的,也比較適用於非等值連接的情況,比如>、>=、<=等情況下的連接(哈希連接只適用於等值連接)。由於Oracle中排序操作的開銷是非常消耗資源的,當結果集很大時排序合並連接的性能很差,於是Oracle在7.3之後推出了新的連接方式——哈希連接。
1, rbo模式;
2, 不等於關聯(> < >= <= <>)
3, hash_join_enabled = false;
4, 數據源已排序
⑵ sql語句中的left join on 中的on是什麼意思on後邊必須跟兩個表中的主鍵欄位嗎
on是篩選條件,篩選兩個表之間的關系,on後面僅要兩表的值有一定的聯系就可以,是值有聯系即可,不必是主鍵
⑶ oracle左連接查詢和右連接查詢隨便舉個例子謝謝!
1、等值連接是最常見的一種連接查詢,通常是在主外鍵關聯關系的表間建立,並將連接條件設定為有關系的列,使用「=」連接相關的表。
⑷ 一條SQL語句不理解,請大俠幫忙解釋。
先分析
Select id from #T a where exists(select 1 from #T where Name=a.Name and ID<a.ID)
這是一個父子關聯EXISTS子查詢語句,資料庫引擎將採取多次測試EXISTS策略輸出父查詢記錄集:
1) 取出父查詢數據源表#T(表別名a)的第一條記錄與子查詢數據源表#T比較連接
ID Name Memo
1 A A1
盡管#T表有3條記錄 Name欄位下為"A",但是這3條記錄的ID欄位下沒有一條記錄滿足小於1的條件,子查詢無滿足條件的行存在,EXISTS測試返回「假」,父查詢第1條記錄被拋棄;
2) 取出父查詢數據源表#T(表別名a)的第二條記錄與子查詢數據源表#T比較連接
ID Name Memo
2 A A2
#T表有3條記錄 Name欄位下為"A",而且者3條記錄下ID欄位有1條(ID=1那條)記錄滿足小於2的條件,子查詢有滿足條件的行存在,EXISTS測試返回「真」,父查詢第2條記錄被保留(ID=2);
3) 取出父查詢數據源表#T(表別名a)的第三條記錄與子查詢數據源表#T比較連接
ID Name Memo
3 A A3
#T表有3條記錄 Name欄位下為"A",而且這3條記錄的ID欄位下有2條(ID=1,D=2)記錄滿足小於3的條件,子查詢有滿足條件的行存在,EXISTS測試返回「真」,父查詢第3條記錄被保留(ID=3);
4) 取出父查詢數據源表#T(表別名a)的第三條記錄與子查詢數據源表#T比較連接
ID Name Memo
4 B B1
盡管#T表有2條記錄 Name欄位下為"B",但是這2條記錄的ID欄位下沒有記錄滿足小於4的條件,子查詢無滿足條件的行存在,EXISTS測試返回「假」,父查詢第4條記錄被拋棄;
5) 取出父查詢數據源表#T(表別名a)的第五條記錄與子查詢數據源表#T比較連接
ID Name Memo
5 B B2
#T表有2條記錄 Name欄位下為"B",而且這2條記錄的ID欄位下有1條(ID=4那條)記錄滿足小於5的條件,子查詢有滿足條件的行存在,EXISTS測試返回「真」,父查詢第5條記錄被保留(ID=5)。
整合前面五次的EXISTS測試結果,該條記錄集返回下列記錄集:
ID
2
3
5
再分析
Select id from #T a where exists(select 1 from #T where Name=a.Name and ID>a.ID)
這是同樣是一個父子關聯EXISTS子查詢語句,資料庫引擎將採取多次測試EXISTS策略輸出父查詢記錄集:
1) 取出父查詢數據源表#T(表別名a)的第一條記錄與子查詢數據源表#T比較連接
ID Name Memo
1 A A1
#T表有3條記錄 Name欄位下為"A",而且這3條記錄的ID欄位下有2條記錄(ID=2和ID=3)滿足大於1的條件,子查詢有滿足條件的行存在,EXISTS測試返回「真」,父查詢第1條記錄被保留(ID=1);
2) 取出父查詢數據源表#T(表別名a)的第二條記錄與子查詢數據源表#T比較連接
ID Name Memo
2 A A2
#T表有3條記錄 Name欄位下為"A",而且者3條記錄下ID欄位有1條(ID=3那條)記錄滿足大於2的條件,子查詢有滿足條件的行存在,EXISTS測試返回「真」,父查詢第2條記錄被保留(ID=2);
3) 取出父查詢數據源表#T(表別名a)的第三條記錄與子查詢數據源表#T比較連接
ID Name Memo
3 A A3
盡管#T表有3條記錄 Name欄位下為"A",但是這3條記錄的ID欄位下沒有記錄滿足大於3的條件,子查詢無滿足條件的行存在,EXISTS測試返回「假」,父查詢第3條記錄被拋棄;
4) 取出父查詢數據源表#T(表別名a)的第三條記錄與子查詢數據源表#T比較連接
ID Name Memo
4 B B1
#T表有2條記錄 Name欄位下為"B",而且這2條記錄的ID欄位下有1條(ID=5那條)記錄滿足大於4的條件,子查詢有滿足條件的行存在,EXISTS測試返回「真」,父查詢第4條記錄被保留(ID=4);
5) 取出父查詢數據源表#T(表別名a)的第五條記錄與子查詢數據源表#T比較連接
ID Name Memo
5 B B2
盡管#T表有2條記錄 Name欄位下為"B",但是這2條記錄的ID欄位下沒有記錄滿足小大5的條件,子查詢無滿足條件的行存在,EXISTS測試返回「假」,父查詢第5條記錄被拋棄。
整合前面五次的EXISTS測試結果,該條記錄集返回下列記錄集:
ID
1
2
4
這里說明一下,使用父子關聯EXISTS子查詢,在WHERE子句里進行關聯欄位比較時,應只採用「=」比較符,至於其它比較符如>,<,<>不建議使用,如果使用的話其返回記錄集會顯得非常詭異,因為這些比較符會導致無法僅從SQL代碼的邏輯上判斷出准確的結果,須要配合數據表中實際存在的數據才能得到正確的結果,因此很不靠譜。父子關聯EXISTS子查詢主要用於求兩表的交集或非交集,無需知道表中的具體記錄就可以准確做出判斷。如果要引入等號以外的比較符最好不要使用EXISTS謂詞。
下面介紹兩個EXISTS謂詞的標准用法:
使用EXIS謂詞求兩表(甲表裡與乙表「有」交集的記錄)的典型寫法:
SELECT * FROM 甲 AS A WHERE
EXISTS(SELECT * FROM 乙 WHERE A.比較欄位=乙.比較欄位)
使用EXIS謂詞求兩表(甲表裡與乙表「無」交集的記錄)的典型寫法:
SELECT * FROM 甲 AS A WHERE
Not EXISTS(SELECT * FROM 乙 WHERE A.比較欄位=乙.比較欄位)
我會就EXISTS謂詞的應用,在不久的將來寫專文說明並發表到本人網路空間上,到時樓主可以過去看看。
⑸ sql server怎麼把多個查詢結果關聯起來
select * from a left join B on a.id=b.id where b.id is null --a的id 不在b表中的
同理
select * from b left join a on a.id=b.id where a.id is null --b的id不在a表中的
⑹ sql 查詢 語句
SQL查詢語句使用詳解
好東東不敢獨享,貼出來大家看看,對編寫資料庫程序有所幫助.
一、簡單查詢
簡單的Transact-SQL查詢只包括選擇列表、FROM子句和WHERE子句。它們分別說明所查詢列、查詢的
表或視圖、以及搜索條件等。
例如,下面的語句查詢testtable表中姓名為「張三」的nickname欄位和email欄位。
SELECT nickname,email
FROM testtable
WHERE name='張三'
(一)選擇列表
選擇列表(select_list)指出所查詢列,它可以是一組列名列表、星號、表達式、變數(包括局部變
量和全局變數)等構成。
1、選擇所有列
例如,下面語句顯示testtable表中所有列的數據:
SELECT *
FROM testtable
2、選擇部分列並指定它們的顯示次序
查詢結果集合中數據的排列順序與選擇列表中所指定的列名排列順序相同。
例如:
SELECT nickname,email
FROM testtable
3、更改列標題
在選擇列表中,可重新指定列標題。定義格式為:
列標題=列名
列名 列標題
如果指定的列標題不是標準的標識符格式時,應使用引號定界符,例如,下列語句使用漢字顯示列
標題:
SELECT 昵稱=nickname,電子郵件=email
FROM testtable
4、刪除重復行
SELECT語句中使用ALL或DISTINCT選項來顯示表中符合條件的所有行或刪除其中重復的數據行,默認
為ALL。使用DISTINCT選項時,對於所有重復的數據行在SELECT返回的結果集合中只保留一行。
5、限制返回的行數
使用TOP n [PERCENT]選項限制返回的數據行數,TOP n說明返回n行,而TOP n PERCENT時,說明n是
表示一百分數,指定返回的行數等於總行數的百分之幾。
例如:
SELECT TOP 2 *
FROM testtable
SELECT TOP 20 PERCENT *
FROM testtable
(二)FROM子句
FROM子句指定SELECT語句查詢及與查詢相關的表或視圖。在FROM子句中最多可指定256個表或視圖,
它們之間用逗號分隔。
在FROM子句同時指定多個表或視圖時,如果選擇列表中存在同名列,這時應使用對象名限定這些列
所屬的表或視圖。例如在usertable和citytable表中同時存在cityid列,在查詢兩個表中的cityid時應
使用下面語句格式加以限定:
SELECT username,citytable.cityid
FROM usertable,citytable
WHERE usertable.cityid=citytable.cityid
在FROM子句中可用以下兩種格式為表或視圖指定別名:
表名 as 別名
表名 別名
例如上面語句可用表的別名格式表示為:
SELECT username,b.cityid
FROM usertable a,citytable b
WHERE a.cityid=b.cityid
SELECT不僅能從表或視圖中檢索數據,它還能夠從其它查詢語句所返回的結果集合中查詢數據。
例如:
SELECT a.au_fname+a.au_lname
FROM authors a,titleauthor ta
(SELECT title_id,title
FROM titles
WHERE ytd_sales>10000
) AS t
WHERE a.au_id=ta.au_id
AND ta.title_id=t.title_id
此例中,將SELECT返回的結果集合給予一別名t,然後再從中檢索數據。
(三)使用WHERE子句設置查詢條件
WHERE子句設置查詢條件,過濾掉不需要的數據行。例如下面語句查詢年齡大於20的數據:
SELECT *
FROM usertable
WHERE age>20
WHERE子句可包括各種條件運算符:
比較運算符(大小比較):>、>=、=、<、<=、<>、!>、!<
范圍運算符(表達式值是否在指定的范圍):BETWEEN…AND…
NOT BETWEEN…AND…
列表運算符(判斷表達式是否為列表中的指定項):IN (項1,項2……)
NOT IN (項1,項2……)
模式匹配符(判斷值是否與指定的字元通配格式相符):LIKE、NOT LIKE
空值判斷符(判斷表達式是否為空):IS NULL、NOT IS NULL
邏輯運算符(用於多條件的邏輯連接):NOT、AND、OR
1、范圍運算符例:age BETWEEN 10 AND 30相當於age>=10 AND age<=30
2、列表運算符例:country IN ('Germany','China')
3、模式匹配符例:常用於模糊查找,它判斷列值是否與指定的字元串格式相匹配。可用於char、
varchar、text、ntext、datetime和smalldatetime等類型查詢。
可使用以下通配字元:
百分號%:可匹配任意類型和長度的字元,如果是中文,請使用兩個百分號即%%。
下劃線_:匹配單個任意字元,它常用來限製表達式的字元長度。
方括弧[]:指定一個字元、字元串或范圍,要求所匹配對象為它們中的任一個。
[^]:其取值也[] 相同,但它要求所匹配對象為指定字元以外的任一個字元。
例如:
限制以Publishing結尾,使用LIKE '%Publishing'
限制以A開頭:LIKE '[A]%'
限制以A開頭外:LIKE '[^A]%'
4、空值判斷符例WHERE age IS NULL
5、邏輯運算符:優先順序為NOT、AND、OR
(四)查詢結果排序
使用ORDER BY子句對查詢返回的結果按一列或多列排序。ORDER BY子句的語法格式為:
ORDER BY {column_name [ASC|DESC]} [,…n]
其中ASC表示升序,為默認值,DESC為降序。ORDER BY不能按ntext、text和image數據類型進行排
序。
例如:
SELECT *
FROM usertable
ORDER BY age desc,userid ASC
另外,可以根據表達式進行排序。
二、聯合查詢
UNION運算符可以將兩個或兩個以上上SELECT語句的查詢結果集合合並成一個結果集合顯示,即執行聯
合查詢。UNION的語法格式為:
select_statement
UNION [ALL] selectstatement
[UNION [ALL] selectstatement][…n]
其中selectstatement為待聯合的SELECT查詢語句。
ALL選項表示將所有行合並到結果集合中。不指定該項時,被聯合查詢結果集合中的重復行將只保留一
行。
聯合查詢時,查詢結果的列標題為第一個查詢語句的列標題。因此,要定義列標題必須在第一個查詢語
句中定義。要對聯合查詢結果排序時,也必須使用第一查詢語句中的列名、列標題或者列序號。
在使用UNION 運算符時,應保證每個聯合查詢語句的選擇列表中有相同數量的表達式,並且每個查詢選
擇表達式應具有相同的數據類型,或是可以自動將它們轉換為相同的數據類型。在自動轉換時,對於數值類
型,系統將低精度的數據類型轉換為高精度的數據類型。
在包括多個查詢的UNION語句中,其執行順序是自左至右,使用括弧可以改變這一執行順序。例如:
查詢1 UNION (查詢2 UNION 查詢3)
三、連接查詢
通過連接運算符可以實現多個表查詢。連接是關系資料庫模型的主要特點,也是它區別於其它類型
資料庫管理系統的一個標志。
在關系資料庫管理系統中,表建立時各數據之間的關系不必確定,常把一個實體的所有信息存放在
一個表中。當檢索數據時,通過連接*作查詢出存放在多個表中的不同實體的信息。連接*作給用戶帶
來很大的靈活性,他們可以在任何時候增加新的數據類型。為不同實體創建新的表,爾後通過連接進行
查詢。
連接可以在SELECT 語句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出連接時有助於
將連接*作與WHERE子句中的搜索條件區分開來。所以,在Transact-SQL中推薦使用這種方法。
SQL-92標准所定義的FROM子句的連接語法格式為:
FROM join_table join_type join_table
[ON (join_condition)]
其中join_table指出參與連接*作的表名,連接可以對同一個表*作,也可以對多表*作,對同一
個表*作的連接又稱做自連接。
join_type 指出連接類型,可分為三種:內連接、外連接和交叉連接。內連接(INNER JOIN)使用比
較運算符進行表間某(些)列數據的比較*作,並列出這些表中與連接條件相匹配的數據行。根據所使用
的比較方式不同,內連接又分為等值連接、自然連接和不等連接三種。
外連接分為左外連接(LEFT OUTER JOIN或LEFT JOIN)、右外連接(RIGHT OUTER JOIN或RIGHT JOIN)
和全外連接(FULL OUTER JOIN或FULL JOIN)三種。與內連接不同的是,外連接不只列出與連接條件相匹
配的行,而是列出左表(左外連接時)、右表(右外連接時)或兩個表(全外連接時)中所有符合搜索條件的
數據行。
交叉連接(CROSS JOIN)沒有WHERE 子句,它返回連接表中所有數據行的笛卡爾積,其結果集合中的
數據行數等於第一個表中符合查詢條件的數據行數乘以第二個表中符合查詢條件的數據行數。
連接*作中的ON (join_condition) 子句指出連接條件,它由被連接表中的列和比較運算符、邏輯
運算符等構成。
無論哪種連接都不能對text、ntext和image數據類型列進行直接連接,但可以對這三種列進行間接
連接。例如:
SELECT p1.pub_id,p2.pub_id,p1.pr_info
FROM pub_info AS p1 INNER JOIN pub_info AS p2
ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)
(一)內連接
內連接查詢*作列出與連接條件匹配的數據行,它使用比較運算符比較被連接列的列值。內連接分
三種:
1、等值連接:在連接條件中使用等於號(=)運算符比較被連接列的列值,其查詢結果中列出被連接
表中的所有列,包括其中的重復列。
2、不等連接: 在連接條件使用除等於運算符以外的其它比較運算符比較被連接的列的列值。這些
運算符包括>、>=、<=、<、!>、!<和<>。
3、自然連接:在連接條件中使用等於(=)運算符比較被連接列的列值,但它使用選擇列表指出查詢
結果集合中所包括的列,並刪除連接表中的重復列。
例,下面使用等值連接列出authors和publishers表中位於同一城市的作者和出版社:
SELECT *
FROM authors AS a INNER JOIN publishers AS p
ON a.city=p.city
又如使用自然連接,在選擇列表中刪除authors 和publishers 表中重復列(city和state):
SELECT a.*,p.pub_id,p.pub_name,p.country
FROM authors AS a INNER JOIN publishers AS p
ON a.city=p.city
(二)外連接
內連接時,返回查詢結果集合中的僅是符合查詢條件( WHERE 搜索條件或 HAVING 條件)和連接條件
的行。而採用外連接時,它返回到查詢結果集合中的不僅包含符合連接條件的行,而且還包括左表(左外
連接時)、右表(右外連接時)或兩個邊接表(全外連接)中的所有數據行。
如下面使用左外連接將論壇內容和作者信息連接起來:
SELECT a.*,b.* FROM luntan LEFT JOIN usertable as b
ON a.username=b.username
下面使用全外連接將city表中的所有作者以及user表中的所有作者,以及他們所在的城市:
SELECT a.*,b.*
FROM city as a FULL OUTER JOIN user as b
ON a.username=b.username
(三)交叉連接
交叉連接不帶WHERE 子句,它返回被連接的兩個表所有數據行的笛卡爾積,返回到結果集合中的數
據行數等於第一個表中符合查詢條件的數據行數乘以第二個表中符合查詢條件的數據行數。
例,titles表中有6類圖書,而publishers表中有8家出版社,則下列交叉連接檢索到的記錄數將等
於6*8=48行。
SELECT type,pub_name
FROM titles CROSS JOIN publishers
ORDER BY type
'-----------------------------------------------------------------------
時間有限,平時在工作中還有很多的查詢技巧.有時間我再搜集貼出來
上一篇:小弟總結的幾個日期時間函數
下一篇:運行時實現組件移動,改變大小
⑺ 關於SQL鏈接查詢的幾種方式
一、概述 通過連接運算符可以實現多個表查詢。連接是關系資料庫模型的主要特點,也是它區別於其它類型資料庫管理系統的一個標志。多表連接查詢是使用Sql的基本操作,但連接的方式卻有多種,熟練使用這些連接方式能夠簡化Sql語句,提高資料庫運行效率。 在關系資料庫管理系統中,表建立時各數據之間的關系不必確定,常把一個實體的所有信息存放在一個表中。當檢索數據時,通過連接操作查詢出存放在多個表中的不同實體的信息。連接操作給用戶帶來很大的靈活性,他們可以在任何時候增加新的數據類型。為不同實體創建新的表,然後通過連接進行查詢。 連接可以在SELECT 語句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出連接時有助於將連接操作與WHERE子句中的搜索條件區分開來。所以,在Transact-SQL中推薦使用這種方法。 二、基本語法與方法 SQL-92標准所定義的FROM子句的連接語法格式為:FROM join_table join_type join_table [ON (join_condition)] 其中join_table指出參與連接操作的表名,連接可以對同一個表操作,也可以對多表操作,對同一個表操作的連接又稱做自連接。 join_type 指出連接類型,可分為三種:內連接、外連接和交叉連接。內連接(INNER JOIN)使用比較運算符進行表間某(些)列數據的比較操作,並列出這些表中與連接條件相匹配的數據行。根據所使用的比較方式不同。 1、內連接又分為等值連接、自然連接和不等連接三種。 2、外連接分為左外連接(LEFT OUTER JOIN或LEFT JOIN)、右外連接(RIGHT OUTER JOIN或RIGHT JOIN)和全外連接(FULL OUTER JOIN或FULL JOIN)三種。與內連接不同的是,外連接不只列出與連接條件相匹配的行,而是列出左表(左外連接時)、右表(右外連接時)或兩個表(全外連接時)中所有符合搜索條件的數據行。 3、交叉連接(CROSS JOIN)沒有WHERE 子句,它返回連接表中所有數據行的笛卡爾積,其結果集合中的數據行數等於第一個表中符合查詢條件的數據行數乘以第二個表中符合查詢條件的數據行數。 連接操作中的ON (join_condition) 子句指出連接條件,它由被連接表中的列和比較運算符、邏輯運算符等構成。 無論哪種連接都不能對text、ntext和image數據類型列進行直接連接,但可以對這三種列進行間接連接。例如:SELECT p1.pub_id,p2.pub_id,p1.pr_info FROM pub_info AS p1 INNER JOIN pub_info AS p2 ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info) (一)內連接 內連接查詢操作列出與連接條件匹配的數據行,它使用比較運算符比較被連接列的列值。內連接分三種: 1、等值連接:在連接條件中使用等於號(=)運算符比較被連接列的列值,其查詢結果中列出被連接表中的所有列,包括其中的重復列。 2、不等連接: 在連接條件使用除等於運算符以外的其它比較運算符比較被連接的列的列值。這些運算符包括>、>=、
⑻ 關於SQL資料庫以及JAVA的一些問題,在線急等
1 付鍵 也就是FK formary key
www.cxrs.net/bbs 程序交流中心,這是專門為新手學習設立的論壇
二、SQL
Structur query language
結構化查詢語言,是操作關系型資料庫中的對象。
DDL(Data definition language 數據定義語言),用於建表或刪表操作,以及對表約束進行修改
create table , alter table , drop table 對表結構的增刪操作。
DML(Data manipulation language 數據操作語言),向表中插入紀錄,修改紀錄
insert , update , delete , merge
transaction ,事務控制語言,由DML語句組成的,commit; ,rollback;
select 查詢語句
dcl 授權語句 grant
三、Oracle
DBMS 資料庫管理系統
有Oracle提供,還提供AS,應用伺服器
DBA 資料庫管理員
四、相關操作
1、sqlplus 訪問資料庫命令(本地訪問/遠程訪問),和資料庫建立連接的命令,是資料庫操作的環境
sqlplus 用戶名/密碼
2、show user 顯示當前用戶的用戶名
改變身份可以直接connect 用戶名/密碼 --- 這個是sqlplus命令
在sqlplus中可以使用 ! 可以在shell和sqlplus間切換,!shell命令 可以在sqlplus中使用shell命令。
實際上是sqlplus開了子進程來執行shell命令。
3、Oracle資料庫中的表分兩類:用戶表(用戶使用操作的表),系統表(資料庫系統維護的表,也叫數據字典)
對用戶表的DDL操作出發了對系統表的DML操作!
五、基本語法
1、select查詢語句
select table_name from user_tables;(查詢系統表)
以上的查詢語句就是查詢本用戶下所擁有的所有表的表名。
投影操作,只查看選擇的欄位的信息。
選擇操作,查看欄位中的特定某些信息。
聯接操作,多表查詢,通過表間連接,查尋出多表中的信息
(1)select table_name from user_tables;(查詢系統表)
以上的查詢語句就是查詢本用戶下所擁有的所有表的表名。
(2)sqlplus的buffer中會緩存最後一條sql語句,可以使用"/"來執行這最後一條sql語句,也可以使用
edit命令來編輯最後一條sql語句。
l命令(list)(sqlplus命令)可以顯示buffer中最後一條命令。
sqlplus命令可以縮寫
(3)desc [表名]
這是一條sqlplus命令,注意他不是sql語句,這條命令用於查看錶的結構。descript的縮寫
[欄位名] [欄位的類型],這是使用完desc命令後顯示的表結構。
(4)select [表的欄位名1],[表的欄位名2], ... from 表名;
select * from 表名; 查尋表中所有欄位的信息
(5)關鍵字不等拆分,sql語句,以及表名,欄位名是大小寫不敏感的。
sql語句要以";"結尾,來表示sql語句結束,如果不加";"系統不會執行此條sql語句,並提示。
在Oracle中字元顯示是左對齊,數值右對齊。
(6)在select 語句中可以使用數學表達式。
select [表達式(必須包含本表欄位名)],[...],.... from 表名;
運算的優先順序的先乘除後加減,同級自左向右運算,括弧改變優先順序。
(7)別名
select [欄位名或表達式] ["別名"],[...] ["..."],.... from 表名;
可以通過在欄位名或表達式後加空格"別名",可以給列,或者表達式結果其別名。
表達別名必須加雙引號。
(8)字元串拼接使用||符號
select 目標欄位名||" "||目標欄位名 from 表名;
注意:在Oracle中的字元串要用'..'包含
別名中需要使用空格,或是大小寫敏感時需要用".."包含。
練習:
自己寫一條SQL語句,執行的結果是select * from ...;
其中...是每張系統表的表名
即在每張系統表的表名前加「select * from」 ,後加「;」
select 'select * from '||table_name||';' from user_tables;
2、處理錯誤
(1)!oerr ora [錯誤號] ,系統可以顯示錯誤的原因和如何修改。如果命令錯誤輸入可以使用edit或ed來修改輸入錯誤。
實際上是在編輯緩存文件中的最後一條sql語句。
也可以使用 (change) c /錯誤欄位/正確欄位,來進行替換操作進行修改。
只有在Linux平台使用
! 相當於 host ,沒有斷連接,只是切換了一下,執行shell命令
(2)edit命令來編輯最後一條sql語句。
3、sqlplus設置
set pause on 回車響應,分屏顯示,只在本會話中有效
set pause off 關閉分屏顯示。
set pause "..." 設置分屏顯示的提示信息。
set pause on 先輸出提示信息,回車響應,分屏顯示
set head off 提頭輸出關閉
set feed off 結尾輸出關閉
set echo off 回寫關閉
spool 文件名.sql 寫入指定文件
spool off 關閉寫入。
4、sql腳本
也就是在文件中寫有sql語句的文件,可以在sqlplus中運行。
引入sql腳本
sqlplus 用戶名/密碼 @sql腳本 (注意:在用戶名密碼輸入結束後一定要加空格然後再寫@sql腳本)
在腳本中最後一行寫上「exit」,則運行完腳本以後,回到shell上
5、
Oracle中的空值 空值會當無窮大處理,其實空值根本就不會存儲,只是看作是無窮大。
Oracle中控制處理函數 NVL(欄位名,值),這個欄位中的空值替換為指定值,如果不為空,則會返回其原值。
例:select (salary*12)*(NVL(commission_pct,0)/100+1) salary,first_name from s_emp;
distinct關鍵字,去掉重復行(這個關鍵字會觸發排序操作)
例: select distinct dept_id,title from s_emp;
dept_id與title的聯合不唯一
注意:distinct,關鍵字之後會對from之前的欄位進行排重操作。
6、column命令 --- sqlplus命令
column命令 列格式的定義
column 目標列名 查看這個類是否定義了格式
column 目標列名 format a.. 設置列寬。
column last_name heading 'Employee|Name' FORMAT A15
設置題頭
這其中的'|'是換行符
column salary justify left format $99,990.00
定義數字顯示格式
注意:如果不滿足顯示的格式,就會把數據顯示為"#"
column salary justify left format $00,000.00
會出現$00,928.00 ,用0補齊
column 列名 clear (清除列格式定義)
注意:只有sqlplus命令才有簡寫,並且在使用sqlplus命令時結尾也不能加分號。
六、選擇操作
1、order by
排序子句 ASC(默認,升序) DESC(降序)
order by 目標列名(別名) 排序順序(不寫排序順序,會默認為升序排序)
例:select first_name from s_emp order by first_name;
select first_name from s_emp order by first_name desc;
注意:升序空值在結果的末尾,降序空值在結果的最前面。
2、where子句
where子句使用在 select ... from ... 後面,用來選擇所需(符合條件的)的記錄
where後面跟的是表達式 也就是 XXX=XXX, XXX between X and X ,XXX in(X,X,X)
like '...' 通配查詢
between ... and ... ,表示結果在這之間,between and是一個閉區間,
也就相當於... <= ... and ... >= ... 。
!=,<>,^=,這三個都標識不等於,<=,>=,=,這些運算符都可以使用。
... in (va1,val2,...) 判斷結果是否在這個枚舉中存在
like '...' 字元串通配查詢,'%'表示多個字元,'_',表示一個字元。
注意:轉義的用法:like 『S\_%』 escape 『\』
... and ... 表示只有兩個條件同時滿足
... or ... 表示條件只要滿足其中只一就可以
all ... 是要求都滿足條件。
not .....,則是可以與以上的條件產生反效果。
空值會對not in造成影響,也就是不等於任何值,但是空值例外。
... is null 使用來判斷值是否為空。
注意:Oracle中的字元串是嚴格區分大小寫的。
(1)注意數據類型,數字類型直接寫,字元用'......' ,預設格式的Date可以用'......',只有別名
才用" "包含。
(2)選擇合適的運算符
七、單行函數
1.字元函數
字元是大小寫敏感的
轉小寫 lower(欄位名) --- 其中的參數可以是一個字元串常量或是一個欄位名
轉大寫 upper(欄位名)
首字母大寫 initcap(欄位名)
字元串拼接 concat(欄位1, 欄位2)
截取子串 substr(欄位名, 起始位置,取字元個數)
al表,是專門用於函數測試和運算的,他只有一條記錄
字元串拼接 concat(...,....)
求指定子串 substr(...,起始位置,取字元個數)
可以使用"-"表示從右向左取,取的時候可以從左往友取。
例:select substr(first_name,-2,2) sub from s_emp;(取後兩個)
select substr(first_name,2,2) sub from s_emp;(取前兩個)
2,數值函數
四捨五入 round(數據,保留小數點後幾位)
可以用負數表示小數點前,0,表示小數點後第一位,也就是保留個位,-1表示個位(保留到十 位)。
例:select round(15.36,1) from al;
截取數字函數 trunc(數據,保留的位數(小數點後位數)) 截取個位之後補0
例:select trunc(123.456,1) from al;
3,日期函數
日期格式,
全日期格式 世紀信息,年月日,時分秒。
預設日期格式,日-月-年 dd-mon-rr
修改當前會話的日期格式,會按照指定的格式輸出日期
alter session set nls_date_format='yyyy mm dd hh24:mi:ss';
返回當前日期 sysdate
例:select sysdate from al;
select sysdate+1 from al; 獲得明天的日期,加1,單位是天
日期是格式敏感的
求兩個日期間相隔了多少個月 months_between(date1,date2)
加減指定數量的月份 add_months(date,月數),月數可以為負,負值就是減去相應的月數。
從date日期開始的第一個星期五 next_day(date,FriDay)
返回月末的日期 last_day(date)
截取日期 trunc(date,'年或月或日或時分秒')
例:select next_day(sysdate,2) from al;
例:select trunc(add_months(sysdate,1),'month') from al;
ROUND('25-MAY-95','MONTH') 01-JUN-95
ROUND('25-MAY-95 ','YEAR') 01-JAN-95
TRUNC('25-MAY-95 ','MONTH') 01-MAY-95
TRUNC('25-MAY-95 ','YEAR') 01-JAN-95
練習:
返回下個月的第一天的日期
select round(last_day(sysdate),'MONTH') from al;
select add_months(trunc(sysdate,'MONTH'),1);
4,不同數據類型間轉換函數
將日期轉成字元 tochar(date,'日期格式')
日期格式要用有效格式,格式大小寫敏感 'yyyy mm dd hh24:mi:ss',
'year'(全拼的年),'mm'(數字表示的月) 'month'(全拼的月),'day'(星期的全拼),'ddspth' (日期的全拼) 'yy mm dd'
例:select to_char(sysdate,'yyyy mm dd hh24:mi:ss')from al;
將字元轉換成數字 to_number('...')
將數字轉字元to_char(number,'fmt') fmt是數字格式
將字元串轉成日期 to_date('...','日期格式')
例:select to_char(to_date('2006 11 03','yyyy mm dd'),'dd-month-yy') from al;
1、等值連接
select [表別名1.欄位名1],[表別名2.欄位名2],...
from 表1 表別名1 ,表2 表別名2
where 表別名1.欄位名3=表別名2.欄位名4;
表連接時,當表與表之間有同名欄位時,可以加上表名或表的別名,加以區分,使用時要用
表名.欄位名或表別名.欄位名(列名)。當表的欄位名是唯一時,可以不用加上表名或表的別名。
注意:當為表起了別名,就不能再使用表名.欄位名。
例:select a.first_name,a.last_name,b.name
from s_emp a,s_dept b
where a.dept_id=b.id;
2、非等值連接
select [表別名1.欄位名1],[表別名2.欄位名2],...
from 表1 表別名1 ,表2 表別名2
where 表別名1.欄位名3 ..... 表別名2.欄位名4
....可以使比較運算符,也可以使其他的除了'='的運算符
例:select e.ename, d.grade,e.sal
from emp e,salgrade d
where e.sal between d.losal and d.hisal;
3、自連接
用別名把一張表中的數據分成兩部分,然後在使用條件過濾。
select [表別名1.欄位名1],[表別名2.欄位名2],...
from 表1 表別名1 ,表1 表別名2
where 表別名1.欄位名3=表別名2.欄位名4;
例:select a.first_name ename,b.first_name cname
from s_emp a,s_emp b
where a.manager_id=b.id;
以上所提到的表連接,都叫做內連接,嚴格匹配兩表的記錄。
4、外連接
會使用一方表中的所有記錄去和另一格表中的記錄按條件匹配,空值也會匹配,這個表中的所有記錄都會顯示,資料庫會模擬出記錄去和那些不匹配的記錄匹配。
例:select a.first_name enamei,a.id,b.first_name cname,b.id
from s_emp a,s_emp b
where a.manager_id=b.id(+);
即用a表中的數據去匹配b表的,若b表中有null,系統模擬紀錄與其匹配
注意:要把那一方的記錄全部都顯示出來,還有注意條件(+)跟在要全部選出的對端。
外連接的應用:
列出哪個部門沒有員工
select e.deptno,d.deptno
from emp e,dept d
where e.deptno(+)=d.deptno
and e.deptno is null;
三、組函數
group 組
group by 分組子句,按指定的分組規則分組 ,這個group by 子句可以跟在 select 語句後或是 having後面。
group by子句也會出發排序操作,會按分組欄位排序。
select [組函數或分組的欄位名] ,... from 表名 group by [欄位名1],[欄位名2],.....;
例:select avg(salary) from s_emp group by dept_id;
注意:組函數可以處理一組數據,返回一個值。
組函數會忽略空值。
avg(..),求平均值,sum(..),求和 這兩個函數的參數只能是number型的。
以下所提到的函數可以使用任意類型做參數。
count(..),用來統計記錄數,可以使用排重命令。count(...)默認使用的是all。
max(..),min(..)求最大值和最小值,
count(*),統計表中記錄數。
例:select max(b.name),avg(a.salary), max(c.name)
from s_emp a,s_dept b,s_region c
where a.dept_id=b.id and b.region_id=c.id
group by b.dept_id;
注意:只要寫了group by子句,
*** select後就只能用group by後的欄位或者是組函數。 ***
where子句只能夠過濾記錄,放單行函數。
having子句可以過濾組函數結果或是分組的信息,且寫在group by子句後。
例:
select max(b.name),avg(a.salary), max(c.name)
from s_emp a,s_dept b,s_region c
where a.dept_id=b.id and b.region_id=c.id
group by b.id
having sum(a.salary)>4000;
column 也可以定義有別名的列的格式。
column "別名" 格式定義
注意:要先過濾掉不需要的記錄,然後再進行分組操作,提高效率。
四、子查詢
子查詢,就是可以嵌在任何的sql語句中的select語句。
在select語句中嵌套子查詢時,會先執行子查詢。一般的會將子查詢放在運算符的右邊。
注意:在使用子查詢時,要注意這個運算符是單行的(也就是只能是單值),還是多行運算符(范圍,多值,in)。
配合使用子查詢返回的結果必須符合運算符的用法。
例:
select first_name,title
from s_emp
where title=any(select title from s_emp
where last_name='Smith')
and upper(last_name)!='SMITH';
select first_name,title
from s_emp
where title in (select title from s_emp
where last_name='Smith')
and upper(last_name)!='SMITH';
五、將業務需求轉換成可操作的表
一: 需求分析
二: 畫E-R圖
三: 轉換成表關系
四: 割接(新老系統交接)
五:
E-R圖屬性:
* 為強制且非空屬性
o 可選屬性(可以有值也可以沒有)
#* 表示此屬性唯一且非空
實體關系:
mastbean maybean
數量關系: 多對一關系
一對多關系
一對一關系
多對多關系
第一範式,所有的屬性都必須是單值,也就是屬性只表示單一的意義。(記錄可以重復,沒有任何限制)
第二範式,屬性要求唯一且非空,(記錄不可重復,但是數據可能會出現冗餘)。
第三範式,非主屬性只能依賴於主屬性,不能依賴於其他非主屬性。(解決數據冗餘問題)
六、約束
約束是針對表中的欄位進行定義的。
primary key (主鍵約束 PK)保證實體的完整性,保證記錄的唯一
主鍵約束,唯一且非空,並且每一個表中只能有一個主鍵,有兩個欄位聯合作為主鍵,只有兩個欄位放在一起唯一標識記錄,叫做聯合主鍵。
foreign key (外建約束 FK)保證引用的完整性,
外鍵約束,外鍵的取值是受另外一張表中的主鍵或唯一值得約束,不能夠取其他值,只能夠引用主鍵會唯一鍵的值,被引用的表,叫做parent table(父表),引用方的表叫做child table(子表),要想創建子表,就要先創建父表,後創建子表,記錄的插入也是如此,先父表後子表,刪除記錄,要先刪除子表記錄,後刪除父表記錄,要修改記錄,如果要修改父表的記錄要保證沒有被子表引用。要刪表時,要先刪子表,後刪除父表。
unuque key(唯一鍵),值為唯一
index(索引)是資料庫特有的一類對象,view(示圖)
典型的一對多 class 對應多個學生。
student table class table
______________________________ _________________________
| id | name | address| class_id| | id |class_desc|class_num|
|(PK)|______|________|___(FK)__| |(pk)|__________|_________|
| | | | | | | | |
一對一
student tabel shenfenzheng table
____________________ _________________________________
| id | name | address| | s_id |shenfen_desc|shenfen_num|
|(PK)|______|________| |(PK,FK)|____________|___________|
| | | | | | | |
多對多
student tabel zhongjian table kecheng table
____________________ _________________________________ __________________
| id | name | address| | s_id |shenfen_desc|shenfen_num| | kid | kechengname|
|(PK)|______|________| |(FK,FK)|____________|___________| | (PK)|____________|
| | | | |聯合主鍵| | | | | |
引用對方表的主鍵,當作本身的主鍵,所以這個表的主鍵,既是主鍵又是外建
建表和其他相關操作
DDL語句
創建表:
create table 表名 ( 欄位名1 類型(數據長度)(default ...) 約束條件, 欄位名2 類型(數據長度) 約束條件 );
Oracle資料庫中的數據類型
varchar(長度),可變長字元串,char(長度) 定長
number(..,..),number 表示浮點數,或者是整數
long 大對象,clog 字元的大對象,相當於文本文件在表中只存放一個相當於只針對值
blog 二進制的大對象,也是以相當於指針的形式存放的。
primary key約束:
主鍵約束的定義:
第一種定義形式:
create table test(c number primary key ); 列級約束
第二種定義形式:
create table test(c number , primary key(c) ) ; 表級約束
create table test( c1 number constraints pkc1 primary key ); 此約束有名字: pkc1
create table test(c number , c2 number , primary key (c ,c1) ) ; 用表級約束可以實現聯合主鍵
foregin key (fk) 外鍵約束:
(先定義父表,再定義子表)
carete table parent(c1 number primary key );
create table child (c number primary key , c2 number references parent(c1));
或表級約束定義:
create table child( c number primary key , c2 number , foreign key(c2) references parent(c1));
如果兩個欄位都為唯一且非空,這時可以定義成UK+NOT NULL
(PK或UK)一對多(FK)
(PK+UK)一對一(FK) 或 (PK)一對一(PK)
多對對多關系,一般都通過一張中間表來分解成兩個一對多的表
建立表
create table[schema]table
schema: 一個用戶對應一個schema 不同用戶下的表不能互相查看
select count(*) from s_dept; <===> select count(*) from sd0611.s_dept;
一個表中只能存儲一個LONG類型
CLOB 存儲大的文本對象
BLOB 存儲大的二進制對象
create table test(c1 number primary key); 設置主鍵
create table test(c1 number constraints test_c1 primary key); 定義約束名,默認約束名為SYS_ 在列後面定義約束稱為列級約束
create table test(c1 number primary key(c1)); 所有列定義完後再定義約束稱為表級約束(能定義聯合主鍵)
cretae table test(c1 number,c2 number,priary key(c1,c2)); 定義聯合主鍵
create table child(c1 number primary key); 先要定義父表
create table child(c1 number primary key, c2 number references parent(c1)); 然後定義子表 references parent定義外鍵
create table child(c1 number primary key, c2 number references parent(c1) on delete cascate); on delete cascate為級聯刪除
create table child(c1 number primary key, c2 number references parent(c1) on delete set null); on delete set null刪除後將外鍵置空
create table child (c1 number primary key, c2 number,foreignkey(c2) references parent(c1));
二、約束
1、非空約束(not null)
這是一個列級約束
在建表時,在數據類型的後面加上 not null ,也就是在插入時不允許插入空值。
例:create table student(id number primary key,name varchar2(32) not null,address varchar2(32));
2、unique 唯一約束
唯一約束,是會忽略空值的,唯一約束,要求插入的記錄中的值是為一的。
例:create table student(id number,name varchar2(32),address varchar2(32),primary key (id),unique (address));
如果創建一個uk,系統自動建一個唯一索引
3、pk、uk
Oralce支持級聯刪除,不支持級聯更新
4、check約束
檢查約束,可以按照指定條件,檢查記錄的插入。check中不能使用尾列,不能使用函數,不能引用其他欄位。
例:create table sal (a1 number , check(a1>1000));
⑼ sql server 等值連接和自然連接的 用法
這是2012年的提問嘛,現在是2019年6月13日,我給你詳細解答。
內連接里分為等值連接和不等連接,自然連接屬於特殊的等值連接。這是他們二者的關系。
這是我建立的兩個表 a和b
相比上圖,少了一個B,對吧
懂了嗎,不懂追問吧
⑽ 關系資料庫如何查詢多表有聯系數據
關聯查詢是日常工作中常用的查詢方式,關聯查詢sql編寫的思路一般如下:1、先確定所連接的表,2、再確定所要查詢的欄位,3、確定連接條件以及連接方式(表連接分類: 內連接、外連接、交叉連接、自連接)
1、內連接:[inner] join on
分類:等值連接、非等值連接
(1)等值連接: 指使用等號"=「比較兩個表的連接列的值,相當於兩表執行笛卡爾後,取兩表連結列值相等的記錄(自然連接是一種特殊的等值連接)(2)非等值連接:指使用」>「或」<"比較兩個表的連接列的值,相當於兩表執行笛卡爾後,取一個表大於或小於另一個表的連結列值的記錄
2、外連接
分類:左外連接、右外連接、全外連接
(1)左外連接:left outer join
連接效果:查詢結果包含左、右兩個表需要查詢的全部行,左側的表中的全部數據都會被顯示出來,但是右側表的數據,只有和左側匹配上的數據才會被查詢出來!否則顯示為null(2)右外連接:right outer join
連接效果:查詢結果包含左、右兩個表需要查詢的全部行,右側的表中的全部數據都會被顯示出來,但是左側表的數據,只有和右側匹配上的數據才會被查詢出來!否則顯示為null(3)全外連接:full/all outer join,查詢結果包含左、右兩個表需要查詢的全部行,對應欄位沒有值顯示null
3、交叉連接
左表中的每一行與右表中的所有行組合,也叫表與表之間做笛卡爾積查詢
4、自連接
當前表與自身的連接查詢,關鍵點在於虛擬化出一張表,即給自身的表定義一個別名