1. 程式人生 > >資料庫高階資料過濾之SQL操作符與SELECT子句

資料庫高階資料過濾之SQL操作符與SELECT子句

高階資料過濾

AND操作符

要通過不止一個列進行果過濾,可以使用AND操作符對WHERE子句附加條件,用在WHERE子句中的關鍵字

OR 操作符

OR操作符與AND操作符正好相反,它告訴DBMS檢索匹配任一條件的行,事實上,許多DBMSORWHERE 子句的第一個條件得到滿足的情況下就不再計算第二個條件了(在第一個條件滿足時,不管第二個條件是否滿足,相應的行都將被檢索出來)

IN 操作符

In操作符用來指定條件範圍,範圍中的每個條件都可以進行匹配,in取一組逗號分隔,括在圓括號中的合法值IN 操作符允許我們在 WHERE 子句中規定多個值。

SQL  IN 語法 

SELECT column_name(s) FROM table_nameWHERE column_nam e IN (value1,value2,...)

IN 操作符例項

SELECT prof_name ,prod_price FROM  Products WHERE vend_id IN(‘DLL01’, ’BRSo1’)ORDER BY prod_name

SELECT 語句檢索由供應商DDL01BRS01製造的所有產品,IN操作符後跟由逗號分隔的合法值,這些值必須在圓括號中.

你會猜測IN 操作符完成了與OR相同的功能,恭喜你答對了,下面的SQL語句完成了與上面的例子相同的工作,

SELECT prod_name,prod_price FROM Products WHERE vend_id=’DDL01’ OR vend_id=’BRS01’ ORDER BY prod_name;

in =的區別

select name from student where name in ('zhang','wang','li','zhao');

select name from student where name='zhang' or name='li' or name='wang' or name='zhao'

的結果是相同的。

為什麼使用IN操作符呢,優點如下:

1.IN操作符的語法更清楚直觀,

2.IN的最大優點是可以包含其他的SELECT語句,能夠更動態地建立WHERE子句,

NOT操作符

WHERE子句中的NOT操作符有且只有一個功能,那就是否定其後所跟的任何條件

,因為NOT從不單獨使用,(他總是與其他操作符一起使用),所以了他的語法與其他操作符有所不同,NOT關鍵字可以用在要過濾的列強,而不僅是在其後.

例項:

列出除了DLL01之外的所有供應商製造的產品

SELECT prod_name FROM Products WHERE NOT vend_id=’DLL01’ ORDER BY prod_name

這裡的NOT否定跟在其後的條件,因此,DBMS不是匹配vend_idDLL01,而是匹配非DLL01之外的所有東西上面的例子也可以使用<>操作符完成

SELECT prod_name FROM Products WHERE NOT vend_id<>’DLL01’ ORDER BY prod_name

在簡單的WHERE子句中NOT沒有什麼優勢,但是在複雜的子句中NOT是非常有用的,例如,在與IN操作符聯合使用時,NOT可以非常簡單地找出與條件列表不匹配的行

any、all、exists 的使用

1. 資料表

有如下資料表:StudentInfo 學員資訊表,表資料如圖1 所示:

ID

NAME

SCORE

CLASSNAME

1

張青青

78

S1101

2

李紅

54

S1101

3

顧小強

86

S1101

4

陳喬

34

S1102

5

韓偉

99

S1102

圖1 學員資訊表資料

其中,ID 代表學員編號,NAME 為學員姓名,SCORE 為學員考試成績,CLASSNAME 為學員所在的班級名稱。

2. any 的使用

編寫 sql 語句查詢:S1101 班哪些學生的成績高於S1102 班的最低成績

SELECT NAME FROM studentInfo WHERE classname='S1101' AND score >(SELECT MIN(score) FROM studentInfo WHERE classname='S1102');

除此之外,我們還可以使用any:

SELECT NAME FROM studentInfo WHERE classname='S1101' AND score >ANY(SELECT score FROM studentInfo WHERE classname='S1102');

3. all 的使用

編寫sql 語句查詢:S1101 班哪些學生的成績高於S1102 班的最高成績

SELECT NAME FROM studentInfo WHERE classname='S1101' AND score >(SELECT MAX(score) FROM studentInfo WHERE classname='S1102');

除此之外,我們還可以使用all:

SELECT NAME FROM studentInfo WHERE classname='S1101' AND score >ALL(SELECT score FROM studentInfo WHERE classname='S1102');

4. exists 的使用

EXISTS 的作用比較簡單,它只關注它後面的子查詢返沒返回值,而不在乎返回多少。如果返回,則整個表示式就為真,否則為假。NOT EXISTS 關鍵字則和EXISTS 作用相反。

假設要查詢有沒有成績為 100 的學生,如果有,則將所有學生的成績都輸出,如果沒有,

則什麼都不輸出,我們使用EXISTS 實現,如下:

SELECT name,score FROM studentInfo WHERE EXISTS(SELECT * FROM studentInfo WHERE score=100);

INEXISTS區別

in 是把外表和內表作hash 連線,而exists是對外表作loop迴圈,每次loop迴圈再對內表進行查詢。

如果查詢的兩個表大小相當,那麼用inexists差別不大。

如果兩個表中一個較小,一個是大表,則子查詢表大的用exists,子查詢表小的用in

例如:表A(小表),表B(大表)

1

select * from A where cc in (select cc from B)

效率低,用到了A表上cc列的索引;

select * from A where exists(select cc from B where cc=A.cc)

效率高,用到了B表上cc列的索引。

相反的

2

select * from B where cc in (select cc from A)

效率高,用到了B表上cc列的索引;

select * from B where exists(select cc from A where cc=B.cc)

效率低,用到了A表上cc列的索引。

not in not exists

如果查詢語句使用了not in 那麼內外表都進行全表掃描,沒有用到索引;

not extsts 的子查詢依然能用到表上的索引。

所以無論那個表大,用not exists都比not in要快。

(記錄合併)unionunion all 的區別

在資料庫中,unionunion all關鍵字都是將兩個結果集合併為一個,但這兩者從使用和效率上來說都有所不同。

union在進行錶鏈接後會篩選掉重複的記錄,所以在錶鏈接後會對所產生的結果集進行排序運算,刪除重複的記錄再返回結果。

如:

 select * from test_union1

   union

 select * from test_union2

      這個SQL在執行時先取出兩個表的結果,再用排序空間進行排序刪除重複的記錄,最後返回結果集,如果表資料量大的話可能會導致用磁碟進行排序。

    union all只是簡單的將兩個結果合併後就返回。這樣,如果返回的兩個結果集中有重複的資料,那麼返回的結果集就會包含重複的資料了。

     從效率上說,union all要比union快很多,所以,如果可以確認合併的兩個結果集中不包含重複的資料的話,那麼就使用union all,如下:

select * from test_union1

union all

select * from test_union2

 使用 union/union all 組合查詢的結果集有兩個最基本的規則:

1。所有查詢中的列數和列的順序必須相同。

2。資料型別必須相容

SELECT子句

Group By子句

首先講講GROUP BY 子句語法:

sql語句Group By用法一則
如果我們的需求變成是要算出每一間店 (store_name) 的營業額 (sales),那怎麼辦呢?在這個情況下,我們要做到兩件事:

第一,我們對於 store_name 及 Sales 這兩個欄位都要選出。

第二,我們需要確認所有的 sales 都要依照各個 store_name 來分開算。這個語法為:   
SELECT "欄位1", SUM("欄位2") FROM "表格名" GROUP BY "欄位1"   

示範
Store_Information 表

store_name

Sales

Date

Los Angeles

$1500

Jan-05-1999

San Diego

$250

Jan-07-1999

Los Angeles

$300

Jan-08-1999

Boston

$700

Jan-08-1999

我們就打入,                                 

SELECT store_name, SUM(Sales)    FROM  Store_Information  GROUP BY store_name   

結果

store_name

SUM(Sales)

Los Angeles

$1800

San Diego

$250

Boston

$700


例子2
SELECT   column1, SUM(column2)  FROM   "list-of-tables"  GROUP BY "column-list";

例子如下:

一個銷售表sales:

workername

salemoney

a1

3000

a2

2000

a3

1000

a2

3000

1.sql要求,查詢每個員工的總銷售總額:

SELECT  workername,SUM(salemoney)  FROM  sales GROUP BY  workername

2.sql要求,查詢總銷售額最大的員工姓名跟銷售額:

SELECT  workername,MAX(salemoney) FROM  sales GROUP BY workername

3.sql要求,查詢總銷售額大於等於2000的員工姓名跟銷售額:

SELECT workername, SUM(salemoney)  FROM sales GROUP BY workername HAVING SUM(salemoney)>=2000


何時使用GROUP BY(心得)

一般業務要求出現 大於,等於,小於,最大,最小等範圍詞語,具體是使用where 還是having,要看是過濾行還是分組,也可同時使用where having

找出具有兩個訂單以上的顧客

SELECT cust_id ,COUNT(*) AS orders FROM Orders GROUP BYcust_id HAVING COUNT(*) >=2

找出具有兩個以上產品且其價格大於等於4的供應商

SELECT vend_id ,count(*) AS num_prods FROM Products WHERE  pro_price>=4 GROUP BY vend_id HAVING COUNT(*)>=2

先找出 產品價格大於等於4的產品 再以供應商分組,返回供應商產品個數資訊,一般having再以返回的資訊作為條件對分組在進行過濾


group by 有一個原則,就是 select 後面的所有列中,沒有使用聚合函式的列,必須出現在 group by 後面,select 列表中指定的列要麼是group by 子句中指定的列,要麼包含聚組函式

說白了就是select 所取出的欄位 在分組裡必須有,但是排除被合計的欄位,比如

select a,b,c from table group by a,b,c這裡 group by 裡 必須有a,b,c
如果改成 select a,b,sum(c) from table groupby a,b,這裡 因為c被合計了 所以按照a,b分組就可以了

同樣的合計函式還包括max count 等等!

group by 除聚合函式外,sum,其他函式,decode,所修飾的資料庫欄位都要在group  by 後體現到

假如一個公司下面有五個工廠,以公司id和工廠id進行group by,那麼出現的結果將會以最小單位來分組,即五條公司名稱相同但是工廠名稱不同的記錄,

Having子句

     在select 語句中可以使用group by 子句將查詢出的行劃分成組,然後,使用聚組函式返回每一個組的彙總資訊,另外,可以使用having子句過濾分組,規定包括哪些分組,排除哪些分組,

   當在gropu by 子句中使用having 子句時,查詢結果中只返回滿足having條件的組。在一個sql語句中可以有where子句和having子句。having 與where 子句類似,均用於設定限定條件,where過濾指定的行,having過濾指定的組,having 子句可以出現聚組函式,在where 子句中不能使用聚組函式。

 SELECT deptno,SUM(sal)  FROM  emp 

WHERE sal>1200

GROUP BY   deptno  

HAVING  SUM(sal)>8500 

  ORDER BY deptno;

一般使用GROUP BY子句時,應該也給出ORDER BY 子句,這是保證資料正確排序的唯一方法
   where 子句的作用是在對查詢結果進行分組前,將不符合where條件的行去掉,即在分組之前過濾資料,條件中不能包含聚組函式,使用where條件顯示特定的行。
   having 子句的作用是篩選滿足條件的組,即在分組之後過濾資料,條件中經常包含聚組函式,使用having 條件顯示特定的組,也可以使用多個分組標準進行分組。

 查詢每個部門的每種職位的僱員數
SELECT  deptno,job,COUNT(*) FROM emp GROUP BY  deptno,job

查出每個供應商的產品數

SELECT vend_id ,COUNT(*) AS num_prods FROM Products GROUP BY vend_id

結果:

vend_id

num_prods

BRS01

3

DLL01

4

FNG01

2

GRUOP BY 子句指示DBMSvend_id排序並分組資料,這就會對每個vend_id而不是整個表計算num_prods一次,從輸出中可以看出,供應商BRS013個產品,供應商DLL014個產品,而供應商FNG012個產品