小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

SQL查詢?nèi)腴T(上篇)

 歆馨 2011-07-19

SQL查詢?nèi)腴T(上篇)

引言

 

      SQL語言是一門簡單易學卻又功能強大的語言,它能讓你快速上手并寫出比較復雜的查詢語句。但對于大多數(shù)開發(fā)者來說,使用SQL查詢數(shù)據(jù)庫并沒有一個抽象 的過程和一個合理的步驟,這很可能會使在寫一些特定的SQL查詢語句來解決特定問題時被”卡”住,本系列文章主要講述SQL查詢時一些基本的理論,以及寫 查詢語句的抽象思路。

 

SQL查詢簡介

      SQL語言起源于1970年E.J.Codd發(fā)表的關系數(shù)據(jù)庫理論,所以SQL是為關系數(shù)據(jù)庫服務的。而對于SQL查詢,是指從數(shù)據(jù)庫中取得數(shù)據(jù)的子集,這句話貌似聽著有些晦澀是吧,下面通過幾張圖片簡單說明一下:

      假如一個數(shù)據(jù)庫中只有一個表,再假如所有數(shù)據(jù)如下圖(取自AdventureWork示例數(shù)據(jù)庫):

    1

 

     而對于子集的概念,look下圖:

 

2       

     最后,子集如下:

 

3

 

    其實,SQL中無論多復雜的查詢,都可以抽象成如上面的過程.

 

精確查詢的前置條件

 

    對于正確取得所需要的數(shù)據(jù)子集.除了需要思路正確并將思路正確轉(zhuǎn)變?yōu)閷猄QL查詢語句之外。還有很重要的一點是需要數(shù)據(jù)庫有著良好的設計.這里的良好設計我所指的是數(shù)據(jù)庫的設計符合業(yè)務邏輯并至少實現(xiàn)第三范式,對于實現(xiàn)第三范式,這只是我個人觀點,對于范式的簡單介紹,請看我的博客:數(shù)據(jù)庫范式那些事.如果數(shù)據(jù)庫設計很糟糕,存在很多冗余,數(shù)據(jù)庫中信息存在大量異常,則即使SQL寫的正確,也無法取得精確的結果。

 

兩種方式,同一種結果

 

    在SQL中,取得相同的數(shù)據(jù)子集可以用不同的思路或不同的SQL語句,因為SQL源于關系數(shù)據(jù)庫理論,而關系數(shù)據(jù)庫理論又源于數(shù)學,思考如何構建查詢語句時,都可以抽象為兩種方法:

    1.關系代數(shù)法

      關系代數(shù)法的思路是對數(shù)據(jù)庫進行分步操作,最后取得想要的結果.

      比如如下語句:

Select Name,Department,Age
From Employee
where Age>20

 

      關系代數(shù)的思路描述上面語句為:對表Employee表進行投影(選擇列)操作,然后對結果進行篩選,只取得年齡大于20的結果.

 

      2.關系演算法

       相比較關系代數(shù)法而言,關系演算法更多關注的是取得數(shù)據(jù)所滿足的條件.上面SQL可以用關系演算法被描述為:我想得到所有年齡大于20的員工的姓名,部門和年齡。

 

     為什么需要兩種方法

 

    對于簡單的查詢語句來說,上面兩種方法都不需要.用腳就可以想出來了。問題在于很多查詢語句都會非常復雜。對于關系演算法來說更多的是關注的是所取出信息 所滿足的條件,而對于關系代數(shù)法來說,更多關注的是如何取出特定的信息.簡單的說,關系演算法表示的是”what”,而關系代數(shù)法表達的 是”how”.SQL語句中所透漏的思路,有些時候是關系代數(shù)法,有些時候是關系演算法,還有些是兩種思路的混合.

     對于某些查詢情況,關系代數(shù)法可能會更簡單,而對于另外一些情況,關系演算法則會顯得更直接.還有一些情況.我們需要混合兩種思路。所以這兩種思維方式在寫SQL查詢時都是必須的.

 

單表查詢

      單表查詢是所有查詢的中間狀態(tài),既是多個表的復雜查詢在最終進行這種連接后都能夠被抽象成單表查詢。所以先從單表查詢開始。

 

選擇列的子集

       根據(jù)上面數(shù)據(jù)子集的說法,選擇列是通過在select語句后面添加所要選擇的列名實現(xiàn)的:

     比如下面數(shù)據(jù)庫中通過在select后面選擇相應的列名實現(xiàn)選擇列的子集.

    5

   相應sql語句如下:

SELECT [Name]
,[GroupName]
FROM [AdventureWorks].[HumanResources].[Department]

 

選擇行的子集

      選擇行的子集是在Sql語句的where子句后面加上相應的限制條件,當where子句后面的表達式為“真”時,也就是滿足所謂的“條件”時,相應的行的子集被返回。

      where子句后面的運算符分為兩類,分別是比較運算符邏輯運算符.

     比較運算符是將兩個相同類型的數(shù)據(jù)進行比較,進而返回布爾類型(bool)的運算符,在SQL中,比較運算符一共有六種,分別為等于(=),小于(& lt;),大于(>),小于或等于(<=),大于或等于(>=)以及不等于(<>),其中小于或等于和大于或等于可以看成 是比較運算符和邏輯運算符的結合體。

      而邏輯運算符是將兩個布爾類型進行連接,并返回一個新的布爾類型的運算符,在SQL中,邏輯運算符通常是將比較運算符返回的布爾類型相連接以最終確定where子句后面滿足條件的真假。邏輯運算符一種有三種,與(AND),或(OR),非(NOT).

  

      6

   比如上面,我想選擇第二條和第六條,為了說明比較運算符和邏輯運算符,可以使用如下Sql語句:

SELECT [Name]
,[GroupName]
FROM [AdventureWorks].[HumanResources].[Department]
WHERE DepartmentID>1 and DepartmentID<3 or DepartmentID>5 and DepartmentID<7

  由此我們可以看出,這幾種運算符是有優(yōu)先級的,優(yōu)先級由大到小排列是比較運算符>于(And)>非(Or)

   當然,運算符也可以通過小括號來改變優(yōu)先級,對于上面那個表

   8

   對于不加括號時:

SELECT *
FROM [AdventureWorks].[HumanResources].[Department]
WHERE DepartmentID>=1 and DepartmentID<=3 and DepartmentID>=5 or DepartmentID<=7

   9

  加了括號改變運算順序后:

SELECT *
FROM [AdventureWorks].[HumanResources].[Department]
WHERE DepartmentID>=1 and DepartmentID<=3 and (DepartmentID>=5 or DepartmentID<=7)

 10

 

很特別的NULL

    假如在一個用戶注冊的表中,一些選填信息并不需要用戶必須填寫,則在數(shù)據(jù)庫中保存為null,這些null值在利用上面where子句后的運算符時,有可能造成數(shù)據(jù)丟失,比如一個選填信息是性別(Gender),假設下面兩條條件子句:

where Gender="M"

 

where NOT (Gender="M")

   由于null值的存在,這兩條語句返回的數(shù)據(jù)行加起來并不是整個表中的所有數(shù)據(jù)。所以,當將null值考慮在內(nèi)時,where后面的條件子句擁有可能的值 從真和假,增加為真,假,以及未知(null)。這些是我們在現(xiàn)實世界中想一些問題的時候可能的答案--真的,假的,我不知道。

    所以我們?nèi)绾卧谶@種情況下不丟失數(shù)據(jù)呢,對于上面的例子來說,如何才能讓整個表的數(shù)據(jù)不被丟失呢,這里必須將除了“真”,“假”以外的“未知”這個選項包含在內(nèi),SQL提供了IS NULL來表明未知這個選項:

where Gender IS NULL

   將上面語句加入進去,則不會再丟失數(shù)據(jù)。

 

排序結果

      上面的那些方法都是關于取出數(shù)據(jù),而下面是關于將取出的子集進行排序。SQL通過Order by子句來進行排序,Order by子句是Sql查詢語句的最后一個子句,也就是說Order by子句之后不能再加任何的子句了。

      Order By子句分為升序(ASC)和降序(DESC),如果不指定升序或者降序,則默認為升序(由小到大),而Order by是根據(jù)排序依據(jù)的數(shù)據(jù)類型決定,分別為3種數(shù)據(jù)類型可以進行排序:

  1. 字符
  2. 數(shù)字
  3. 時間日期

     字符按照字母表進行排序,數(shù)字根據(jù)數(shù)字大小排序,時間日期根據(jù)時間的先后進行排序。

     

其它一些有關的

  視圖

       視圖可以看作是一個保存的虛擬表,也可以簡單看做是保存的一個查詢語句。視圖的好處是視圖可以根據(jù)視圖所查詢表的內(nèi)容的改變而改變,打個比方來理解這句話是:

    12

     使用視圖的優(yōu)點是可以對查詢進行加密以及便于管理,據(jù)說還可以優(yōu)化性能(我不認可這點).

 

防止重復

       有時候我們對于取出的數(shù)據(jù)子集不想重復,比如你想知道一些特定的員工一共屬于幾個部門

SELECT [EmployeeID]
,[DepartmentID]
FROM [AdventureWorks].[HumanResources].[EmployeeDepartmentHistory]

15

   這樣的結果是沒有意義的,SQL提供了Distinct關鍵字來實現(xiàn)這點:

SELECT distinct DepartmentID
FROM [AdventureWorks].[HumanResources].[EmployeeDepartmentHistory]
16

 

 

聚合函數(shù)

     所謂聚合函數(shù),是為了一些特定目的,將同一列多個值聚合為一個,比如我想知道一群人中最大年齡是多少可以利用MAX(Age),比如我想知道一個班級平均測驗成績是多少可以用AVG(Result)……

 

 

 

總結

     文章簡單概述了SQL查詢的原理以及簡單的單表查詢,這些都是數(shù)據(jù)庫查詢的基礎概念,對于進行復雜查詢來說,弄明白這些概念是必不可少的。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多