經典SQL回顧之晉級篇


     上篇博文在說SQL基礎的時候,有一個地方有點誤導大家,文中說到SQL 中的substring()和C#中的substring()相同,這有點歧義。基本原理雖然相同,但是有一點很不一樣,就是C#中索引是從0開始的,而SQL中索引是從1開始的,所以在截取的時候需要稍微注意一下,在這里也感謝給我指出來的那位朋友。其實我們很多時候在閱讀別人文章的時候,如果發現其中不妥的地方,耐心的,而且清楚的指出來,不但對自己是一種提高,對作者也是一種鼓勵。因為很多時候,自己能明白是一回事兒,但要描述清楚,讓別人明白又是另外一回事兒。好了,開頭說了幾句題外話,現在切入正題。

      索引-->Index,可以對經常需要查詢的字段添加索引,從而增加訪問速率,提高檢索速度。如果說索引不太好理解,咱們換個說法,書的目錄大家都知道,通俗的說,索引跟目錄挺相似的。有了目錄,我們可以很方便,快捷的查詢書中的內容,這比一頁一頁翻效率要高的多。但是,書中的內容一發生變化,我們要想目錄還有效的話,就得及時的更改目錄。索引也一樣,雖然很多時候可以提高效率,但是如果庫中的數據頻繁變化的話,用不用索引就得論證一下了。另外索引占空間,而且添加,更新,刪除數據時也需要同步更新,因此降低了Insert,Update,Delete的速度,所以只在經常檢索的字段上創建索引。還有一個地方要注意的就是,為了避免全表掃描,盡量別在索引里用like之類的模糊查詢。

      IN,邏輯運算符,用來查找值屬於指定結婚的元組,格式用法:

//語法格式
//列名  [not] IN (常量1,常量2,常量3......)
//例:
SELECT Sname,Ssex from Student where sdept

IN ('信息系','計算機系','數學系')

//查詢表中系別為信息系,計算機系或者數學系的學生
View Code

      SQL中常用的字符匹配

      _ 匹配任意一個字符     %匹配0或多個字符     [] 匹配 []中的任意一個字符    [^ ]不匹配[]中的任意一個字符

     請看示例:     

SELECT ......Sname like '張%'  --查姓張的學生信息
SELECT ......Sname like '[張李劉]%' --查姓張,姓劉,或者姓李的學生信息
SELECT ......Sname like '_[小大]%'--查名字中第二個字為大或者小的學生
SELECT ......Sname not like '劉%' --查所有不姓劉的學生信息
SELECT ......Sno like '%[^235]' --查學號最后一位不是2,3,5的學生信息
View Code

     連接查詢:我們在做SQL設計時,不可能將所有的信息都放入一個表,所以在查詢信息的時候經常需要聯合幾個表來查詢。不管是什么數據庫,Oracle,MS SQL,DB2或者是Sybase,獲取信息時連接查詢都不可避免。本文將簡單的說一下幾個不同的連接,包括:內連接,自連接和外連接。

      內連接:Inner join邏輯運算符返回滿足第一個(頂端)輸入與第二個(底端)輸入聯接的每一行。這個和用select查詢多表是一樣的效果,所以內連接用的比較少。還有一點要說明的就是Join 默認就是inner join。 所以我們在寫內連接的時候可以省略inner 這個關鍵字。例:     

//格式:select xxxx from 表1 join 表2 on 條件
select student.sno,sname......from student join sc
on student.sno=sc.sno
View Code

      自連接:相互連接的表在物理上為同一張表,但在邏輯上可以分為兩張。使用自連接時必須為兩個表取別名。如:查詢與范冰冰在同一系學習的學生姓名和所在系。我們可以按這個思路來:先找到范冰冰在哪個系學習,在學生表中將這個表稱為s1,然后找出此系所有學生,在student表中將這個表稱為s2,s1和s2連接的條件就是兩個表的系別相同。

select s2.sname,s2.sdept from student s2 join student s1
on s1.sdept=s2.sdept where s1.name='范冰冰'
and s2.name!='范冰冰'
View Code

      外連接:外連接又分左(外)連接,右(外)連接,全(外)連接。左外連接和右外連接時都會以一張表為基表,該表的內容會全部顯示,然后加上兩張表匹配的內容。 如果基表的數據在另一張表沒有記錄。 那么在相關聯的結果集行中列顯示為空值(NULL)。形如:

      from 表1 left|right join 表2 on 條件   左連接的含義是限制表2中的數據必須滿足連接條件,而不管表1中的數據是否滿足連接條件,均會輸出表1中的內容。右連接則正好相反。說了這么多連接可能還是有點迷糊,我也看過其他一些寫SQL連接的文章,有一篇還真不錯,這里借鑒一些:

      關於內連接:

//1.2.1 先創建2張測試表並插入數據:
SQL> select * from dave;
ID  NAME
---------- ----------
1  dave
2  bl
1  bl
2  dave
SQL> select * from bl;
ID  NAME
---------- ----------
1  dave
2  bl
//1.2.3 用內鏈接進行查詢:
SQL> Select a.id,a.name,b.name from dave a inner join bl b on a.id=b.id;   -- 標准寫法
        ID NAME       NAME
---------- ---------- ----------
         1 dave       dave
         2 bl         bl
         1 bl         dave
         2 dave       bl
SQL> Select a.id,a.name,b.name from dave a join bl b on a.id=b.id;  -- 這里省略了inner 關鍵字
        ID NAME       NAME
---------- ---------- ----------
         1 dave       dave
         2 bl         bl
         1 bl         dave
         2 dave       bl
SQL> Select a.id,a.name,b.name from dave a,bl b where a.id=b.id;  -- select 多表查詢
        ID NAME       NAME
---------- ---------- ----------
         1 dave       dave
         2 bl         bl
         1 bl         dave
         2 dave       bl
View Code

      外連接:

--以下為模擬數據
SQL> select * from bl;
        ID NAME
---------- ----------
         1 dave
         2 bl
         3 big bird
         4 exc
         9 懷寧
SQL> select * from dave;
        ID NAME
---------- ----------
         8 安慶
         1 dave
         2 bl
         1 bl
         2 dave
         3 dba
         4 sf-express
         5 dmm
View Code

    左外連接(Left outer join/ left join)

    left join是以表的記錄為基礎的,示例中Dave可以看成左表,BL可以看成右表,它的結果集是Dave表中的數據,在加上Dave表和BL表匹配的數據。換句話說,左表(Dave)的記錄將會全部表示出來,而右表(BL)只會顯示符合搜索條件的記錄BL表記錄不足的地方均為NULL.右外連接的結果和左外連接相反,就不舉例了。

示例:
SQL> select * from dave a left join bl b on a.id = b.id;
       ID NAME               ID NAME
--------- ---------- ---------- ----------
        1 bl                  1 dave
        1 dave                1 dave
        2 dave                2 bl
        2 bl                  2 bl
        3 dba                 3 big bird
        4 sf-express          4 exc
        5 dmm                             -- 此處B表為null,因為沒有匹配到
        8 安慶                             -- 此處B表為null,因為沒有匹配到
SQL> select * from dave a left outer join bl b on a.id = b.id;
        ID NAME               ID NAME
---------- ---------- ---------- ----------
         1 bl                  1 dave
         1 dave                1 dave
         2 dave                2 bl
         2 bl                  2 bl
         3 dba                 3 big bird
         4 sf-express          4 exc
         5 dmm
         8 安慶
View Code

    以下這張圖-1很好的表示了各連接的關系。

 

    視圖: 從數據庫的基本表中選取出來的數據組成的邏輯窗口,數據庫中只存放視圖的定義,而不包含數據,其數據仍放在原表中。

    1、單原表視圖,顧名思義,從一個表中查詢出來的數據,如:    

create view is_student
as
select sno,sname,sage
from student where sdept='計算機系'
View Code

    2、多原表視圖(建立計算機系選修了‘c01’的視圖)

create view v_s1(sno,sname,grade)
as
select student.sno,sname,grade
from student join sc on student.sno=sc.sno
where sdept='計算機系' and sc.cno='c01'
View Code

     3、在已有的視圖上定義新的視圖。類似於2,刪除視圖:drop view<viewname>

     由於時間關系,其他的內容放到下篇寫吧,希望小伙伴們能夠多多包含!謝謝。

     下篇會介紹一下存儲過程,事務和函數,以及個人之前在面試的時候遇到的幾個經典的SQL問題,還有個人用的幾個比較高效的SQL寫法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM