佳木斯湛栽影视文化发展公司

主頁(yè) > 知識(shí)庫(kù) > SQL查詢?nèi)腴T(上篇) 推薦收藏

SQL查詢?nèi)腴T(上篇) 推薦收藏

熱門標(biāo)簽:服務(wù)外包 百度競(jìng)價(jià)排名 地方門戶網(wǎng)站 AI電銷 鐵路電話系統(tǒng) 呼叫中心市場(chǎng)需求 網(wǎng)站排名優(yōu)化 Linux服務(wù)器

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

SQL查詢簡(jiǎn)介
SQL語(yǔ)言起源于1970年E.J.Codd發(fā)表的關(guān)系數(shù)據(jù)庫(kù)理論,所以SQL是為關(guān)系數(shù)據(jù)庫(kù)服務(wù)的。而對(duì)于SQL查詢,是指從數(shù)據(jù)庫(kù)中取得數(shù)據(jù)的子集,這句話貌似聽(tīng)著有些晦澀是吧,下面通過(guò)幾張圖片簡(jiǎn)單說(shuō)明一下:
假如一個(gè)數(shù)據(jù)庫(kù)中只有一個(gè)表,再假如所有數(shù)據(jù)如下圖(取自AdventureWork示例數(shù)據(jù)庫(kù)):
  1

 

     而對(duì)于子集的概念,look下圖:

 

2       

     最后,子集如下:

 

3

    其實(shí),SQL中無(wú)論多復(fù)雜的查詢,都可以抽象成如上面的過(guò)程.

精確查詢的前置條件
對(duì)于正確取得所需要的數(shù)據(jù)子集.除了需要思路正確并將思路正確轉(zhuǎn)變?yōu)閷?duì)應(yīng)SQL查詢語(yǔ)句之外。還有很重要的一點(diǎn)是需要數(shù)據(jù)庫(kù)有著良好的設(shè)計(jì).這里的良好設(shè)計(jì)我所指的是數(shù)據(jù)庫(kù)的設(shè)計(jì)符合業(yè)務(wù)邏輯并至少實(shí)現(xiàn)第三范式,對(duì)于實(shí)現(xiàn)第三范式,這只是我個(gè)人觀點(diǎn),對(duì)于范式的簡(jiǎn)單介紹,請(qǐng)看我的博客:數(shù)據(jù)庫(kù)范式那些事.如果數(shù)據(jù)庫(kù)設(shè)計(jì)很糟糕,存在很多冗余,數(shù)據(jù)庫(kù)中信息存在大量異常,則即使SQL寫的正確,也無(wú)法取得精確的結(jié)果。
兩種方式,同一種結(jié)果
在SQL中,取得相同的數(shù)據(jù)子集可以用不同的思路或不同的SQL語(yǔ)句,因?yàn)镾QL源于關(guān)系數(shù)據(jù)庫(kù)理論,而關(guān)系數(shù)據(jù)庫(kù)理論又源于數(shù)學(xué),思考如何構(gòu)建查詢語(yǔ)句時(shí),都可以抽象為兩種方法:
1.關(guān)系代數(shù)法
關(guān)系代數(shù)法的思路是對(duì)數(shù)據(jù)庫(kù)進(jìn)行分步操作,最后取得想要的結(jié)果.
比如如下語(yǔ)句:

復(fù)制代碼 代碼如下:

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

關(guān)系代數(shù)的思路描述上面語(yǔ)句為:對(duì)表Employee表進(jìn)行投影(選擇列)操作,然后對(duì)結(jié)果進(jìn)行篩選,只取得年齡大于20的結(jié)果.
2.關(guān)系演算法
相比較關(guān)系代數(shù)法而言,關(guān)系演算法更多關(guān)注的是取得數(shù)據(jù)所滿足的條件.上面SQL可以用關(guān)系演算法被描述為:我想得到所有年齡大于20的員工的姓名,部門和年齡。
為什么需要兩種方法
對(duì)于簡(jiǎn)單的查詢語(yǔ)句來(lái)說(shuō),上面兩種方法都不需要.用腳就可以想出來(lái)了。問(wèn)題在于很多查詢語(yǔ)句都會(huì)非常復(fù)雜。對(duì)于關(guān)系演算法來(lái)說(shuō)更多的是關(guān)注的是所取出信息所滿足的條件,而對(duì)于關(guān)系代數(shù)法來(lái)說(shuō),更多關(guān)注的是如何取出特定的信息.簡(jiǎn)單的說(shuō),關(guān)系演算法表示的是”what”,而關(guān)系代數(shù)法表達(dá)的是”how”.SQL語(yǔ)句中所透漏的思路,有些時(shí)候是關(guān)系代數(shù)法,有些時(shí)候是關(guān)系演算法,還有些是兩種思路的混合.
對(duì)于某些查詢情況,關(guān)系代數(shù)法可能會(huì)更簡(jiǎn)單,而對(duì)于另外一些情況,關(guān)系演算法則會(huì)顯得更直接.還有一些情況.我們需要混合兩種思路。所以這兩種思維方式在寫SQL查詢時(shí)都是必須的.
單表查詢
單表查詢是所有查詢的中間狀態(tài),既是多個(gè)表的復(fù)雜查詢?cè)谧罱K進(jìn)行這種連接后都能夠被抽象成單表查詢。所以先從單表查詢開(kāi)始。
選擇列的子集
根據(jù)上面數(shù)據(jù)子集的說(shuō)法,選擇列是通過(guò)在select語(yǔ)句后面添加所要選擇的列名實(shí)現(xiàn)的:
比如下面數(shù)據(jù)庫(kù)中通過(guò)在select后面選擇相應(yīng)的列名實(shí)現(xiàn)選擇列的子集.

    5

   相應(yīng)sql語(yǔ)句如下:

復(fù)制代碼 代碼如下:

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

選擇行的子集
選擇行的子集是在Sql語(yǔ)句的where子句后面加上相應(yīng)的限制條件,當(dāng)where子句后面的表達(dá)式為“真”時(shí),也就是滿足所謂的“條件”時(shí),相應(yīng)的行的子集被返回。

where子句后面的運(yùn)算符分為兩類,分別是比較運(yùn)算符和邏輯運(yùn)算符.

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

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

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

復(fù)制代碼 代碼如下:

SELECT [Name]
,[GroupName]
FROM [AdventureWorks].[HumanResources].[Department]
WHERE DepartmentID>1 and DepartmentID3 or DepartmentID>5 and DepartmentID7

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

   當(dāng)然,運(yùn)算符也可以通過(guò)小括號(hào)來(lái)改變優(yōu)先級(jí),對(duì)于上面那個(gè)表

   8

   對(duì)于不加括號(hào)時(shí):

復(fù)制代碼 代碼如下:

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

9
加了括號(hào)改變運(yùn)算順序后:
復(fù)制代碼 代碼如下:

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

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

where Gender="M"
where NOT (Gender="M")

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

所以我們?nèi)绾卧谶@種情況下不丟失數(shù)據(jù)呢,對(duì)于上面的例子來(lái)說(shuō),如何才能讓整個(gè)表的數(shù)據(jù)不被丟失呢,這里必須將除了“真”,“假”以外的“未知”這個(gè)選項(xiàng)包含在內(nèi),SQL提供了IS NULL來(lái)表明未知這個(gè)選項(xiàng):
where Gender IS NULL 將上面語(yǔ)句加入進(jìn)去,則不會(huì)再丟失數(shù)據(jù)。

排序結(jié)果
上面的那些方法都是關(guān)于取出數(shù)據(jù),而下面是關(guān)于將取出的子集進(jìn)行排序。SQL通過(guò)Order by子句來(lái)進(jìn)行排序,Order by子句是Sql查詢語(yǔ)句的最后一個(gè)子句,也就是說(shuō)Order by子句之后不能再加任何的子句了。

Order By子句分為升序(ASC)和降序(DESC),如果不指定升序或者降序,則默認(rèn)為升序(由小到大),而Order by是根據(jù)排序依據(jù)的數(shù)據(jù)類型決定,分別為3種數(shù)據(jù)類型可以進(jìn)行排序:
字符
數(shù)字
時(shí)間日期
字符按照字母表進(jìn)行排序,數(shù)字根據(jù)數(shù)字大小排序,時(shí)間日期根據(jù)時(shí)間的先后進(jìn)行排序。

其它一些有關(guān)的
視圖
視圖可以看作是一個(gè)保存的虛擬表,也可以簡(jiǎn)單看做是保存的一個(gè)查詢語(yǔ)句。視圖的好處是視圖可以根據(jù)視圖所查詢表的內(nèi)容的改變而改變,打個(gè)比方來(lái)理解這句話是:
12

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

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

復(fù)制代碼 代碼如下:

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

15 
這樣的結(jié)果是沒(méi)有意義的,SQL提供了Distinct關(guān)鍵字來(lái)實(shí)現(xiàn)這點(diǎn):

復(fù)制代碼 代碼如下:

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

16 
聚合函數(shù)
所謂聚合函數(shù),是為了一些特定目的,將同一列多個(gè)值聚合為一個(gè),比如我想知道一群人中最大年齡是多少可以利用MAX(Age),比如我想知道一個(gè)班級(jí)平均測(cè)驗(yàn)成績(jī)是多少可以用AVG(Result)……
總結(jié)
文章簡(jiǎn)單概述了SQL查詢的原理以及簡(jiǎn)單的單表查詢,這些都是數(shù)據(jù)庫(kù)查詢的基礎(chǔ)概念,對(duì)于進(jìn)行復(fù)雜查詢來(lái)說(shuō),弄明白這些概念是必不可少的。

標(biāo)簽:湖南 銅川 湘潭 衡水 蘭州 黃山 仙桃 崇左

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《SQL查詢?nèi)腴T(上篇) 推薦收藏》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    六安市| 宕昌县| 武夷山市| 平顺县| 沭阳县| 西丰县| 汝阳县| 南乐县| 柳林县| 德江县| 盐边县| 通州市| 收藏| 都昌县| 那曲县| 方城县| 南陵县| 腾冲县| 秀山| 竹北市| 平邑县| 全南县| 郁南县| 清苑县| 内乡县| 原阳县| 株洲市| 东平县| 玉林市| 武冈市| 铁岭县| 阿克苏市| 普安县| 南康市| 岚皋县| 沁阳市| 阜城县| 张家界市| 醴陵市| 若尔盖县| 五家渠市|