向瑜
摘要:本文針對(duì)關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)中SQL查詢語句的一些基本用法,作了一些簡(jiǎn)單的介紹,起著拋磚引玉的功效。通過本文的介紹,力圖幫助學(xué)生更好地掌握此語句的用法。
關(guān)鍵詞:SELECT語句查詢連接
在關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)中,SQL查詢語句——SELECT的使用是非常重要的一部分內(nèi)容,是任何SQL語言中使用頻率最高的語句,它是SQL語言的靈魂。SELECT語句可以使數(shù)據(jù)庫(kù)服務(wù)器根據(jù)客戶的要求搜索所需要的信息,并按規(guī)定的格式返回給客戶。使用T—SQL的SELECT語句,不僅可以查詢普通數(shù)據(jù)庫(kù)中的表格和視圖信息,還可以查詢SQL Server的系統(tǒng)信息。在Transact-SQL中絕大多數(shù)的語句都是由SELECT構(gòu)成的。
然而筆者在近幾年對(duì)關(guān)系數(shù)據(jù)庫(kù)管理軟件(如Access、SQL Server、Oracle等)的教學(xué)中,發(fā)現(xiàn)對(duì)于這部分的內(nèi)容學(xué)生掌握得并不是很好。為此,筆者根據(jù)多年的教學(xué)經(jīng)驗(yàn),將SQL查詢語句的一些使用技巧列出來,供學(xué)生參考和同行借鑒。
由于SELECT語句的完整語句比較復(fù)雜,故在這里只列舉出它的主要子句。SELECE語句的主要子句格式如下:
SELECT [ALL|DISTINCT][TOP n] select_list
[INTO new_table]
[FROM table_condition]
[WHERE search_condition]
[GROUP BY group_by_expression]
[HAVING search_condition]
[ORDER BY order_by_expression [ASC|DESC]]
[COMPUTE expression]
下面筆者就結(jié)合簡(jiǎn)單查詢、聯(lián)合查詢和連接查詢?nèi)矫嫱ㄟ^舉例的形式來談?wù)動(dòng)嘘P(guān)Transact-SQL語句的用法。(注:以下所有例子的數(shù)據(jù)表來自示例數(shù)據(jù)庫(kù)“圖書管理系統(tǒng)”或“northwind”,在進(jìn)行查詢前,先用USE關(guān)鍵字將相關(guān)數(shù)據(jù)庫(kù)打開。)
1 簡(jiǎn)單查詢
Transact-SQL的簡(jiǎn)單查詢包括選擇列表、FROM子句和WHERE子句三部分內(nèi)容。由此說明要查詢的列、所查詢的表或視圖以及檢索條件等。
例如,從數(shù)據(jù)庫(kù)“圖書管理系統(tǒng)”的“圖書明細(xì)表”中查詢定價(jià)大于50的“圖書編號(hào)”、“圖書名稱”、“出版日期”和“定價(jià)”字段的信息。
SELECT圖書編號(hào),圖書名稱,出版日期,定價(jià)
FROM 圖書明細(xì)表
WHERE 定價(jià)>50
1.1 選擇列表
簡(jiǎn)單查詢中的選擇列表(select_list)指出要查詢的字段列,可以由一組字段名列表、星號(hào)、表達(dá)式或變量(包括局部變量和全局變量)等構(gòu)成。
1.1.1 查詢表中所有的字段列
星號(hào)(*)在選擇列表中有特殊含義,它代表列表中的所有行。
例如,從數(shù)據(jù)庫(kù)“圖書管理系統(tǒng)”中查詢“出版社信息表”的所有行。
SELECT *
FROM 出版社信息表
1.1.2 查詢表中指定的列
可以從表中檢索指定的列,只需將這些列放在選擇列表中。
例如,從數(shù)據(jù)庫(kù)“圖書管理系統(tǒng)”的“作者表”中查詢列為“作者姓名”、“性別”和“電話”的作者信息。
SELECT作者姓名,性別,電話
FROM作者表
1.1.3 改變列名
在選擇列表中,通過使用AS關(guān)鍵字創(chuàng)建更具可讀性的別名來取代默認(rèn)的列名。
定義格式為:列標(biāo)題AS列名或列名列標(biāo)題
注意:如果指定的列名不是標(biāo)準(zhǔn)的標(biāo)識(shí)符格式,應(yīng)使用引號(hào)定界符。
例如,從數(shù)據(jù)庫(kù)“圖書管理系統(tǒng)”的“圖書明細(xì)表”中,查詢列“圖書名稱”和“定價(jià)”為八折后的“新價(jià)格”的圖書信息。
SELECT圖書名稱,定價(jià)*0.8 AS新價(jià)格
FROM圖書明細(xì)表
1.1.4 消除重復(fù)行
如果希望一個(gè)列表沒有重復(fù)值,則可以使用DISTINCT子句來消除結(jié)果集中的重復(fù)行。
例如,從數(shù)據(jù)庫(kù)“northwind”的“suppliers”表中檢索所有的行,但每個(gè)國(guó)家只顯示一次。
SELECT DISTINCT country
FROM suppliers
1.1.5 使用TOPn列出前n個(gè)記錄
用TOPn[PERCENT]關(guān)鍵字列出結(jié)果集中前n個(gè)記錄。其中TOPn表示返回結(jié)果集中前n行記錄,而TOP n PERCENT中的n表示一百分?jǐn)?shù),指定返回的記錄數(shù)等于總記錄數(shù)的百分之幾。
例如,從數(shù)據(jù)庫(kù)“northwind”的“order details”表中查詢出前5條記錄,只顯示orderid、productid、quantity三列內(nèi)容。
SELECT TOP 5 orderid,roductid,quantity
FROM [order details]
1.2 FROM子句
1.2.1 FROM子句指定從中查詢行和列所屬的源表或視圖。可以指定多個(gè),最多達(dá)256個(gè),其間用“,”分隔。當(dāng)FROM子句同時(shí)指定多個(gè)表或視圖時(shí),如果在選擇列表中有相同的列,則應(yīng)使用對(duì)象名限定這些列所屬的表或視圖。
例如,在數(shù)據(jù)庫(kù)“northwind”的“orders”和“customers”兩個(gè)表中均有customerid(顧客id)列,在查詢兩個(gè)表中的顧客id時(shí)應(yīng)使用下面語句格式來限定。
SELECT DISTINCT customerid,companyname,orderdate,
FROM orders,customers
WHERE orders. customerid = customers. customerid
1.2.2 在FROM子句中可以為表或視圖指定別名。格式:<表名> as <別名>或<表名> <別名>
例如,上面例中的查詢語句也可表示為如下形式:SELECT DISTINCT customerid,companyname,orderdate,
FROM orders a,customers b
WHERE a.customerid = b. customerid
1.3 WHERE子句
1.3.1 使用WHERE子句,可以根據(jù)給定的搜索條件檢索特定的行。
例如,下面的查詢將從數(shù)據(jù)庫(kù)“northwind”中的“employees”表中檢索所有居住在美國(guó)的職員的姓和居住的城市。
SELECT lastname,city
FROM employees
WHERE country=USA
1.3.2 在WHERE子句中可包括以下一些運(yùn)算符:①比較運(yùn)算符(用于比較大小):>(大于)、>=(大于或等于)、=(等于)、<(小于)、<=(小于或等于)、<>(不等于)。②范圍運(yùn)算符(檢索在指定取值范圍內(nèi)的行):BETWEEN…AND…和NOT BETWEEN…AND…。例:unitprice BETWEEN 10 AND 30等價(jià)于unitprice>=10 AND unitprice<=30。③列表運(yùn)算符(檢索與指定值列表相匹配的行):IN (項(xiàng)1,項(xiàng)2,……)和NOT IN (項(xiàng)1,項(xiàng)2,……)。例:country IN ('Germany','China')。④字符串比較符(通過字符串比較來選擇符合條件的行):LIKE和NOT LIKE,適用于char、nchar、varchar、nvarchar、binary、varbinary、datetime或smalldatetime等數(shù)據(jù)類型的查詢,以及在特定條件下對(duì)text、ntext和image數(shù)據(jù)類型進(jìn)行的查詢。
采用以下四種通配符來形成字符串搜索條件:a百分號(hào)%:包含零個(gè)或更多字符的任意字符串。b下劃線_:匹配任何單個(gè)字符。c方括號(hào)[]:指定的范圍或集合內(nèi)的任何單個(gè)字符。d[^]:不在指定的范圍或集合內(nèi)的任何單個(gè)字符。
例如,用LIKE ‘N%來表示以N開頭的任意字符串;
用LIKE ‘N[xy]%表示以N開頭,第二個(gè)字符是x或y的字符串;
用LIKE ‘N[^xy]%表示以N開頭,第二個(gè)字符不是x或y的字符串;
用LIKE ‘N_M%表示以N開頭,第三個(gè)字符是M,第二個(gè)為任意一個(gè)字符的字符串。
⑤空值判斷符(檢索那些指定列中遺漏信息的行):IS NULL和NOT IS NULL。
例如,從數(shù)據(jù)庫(kù)“northwind”的“suppliers”表中檢索fax列為空的公司列表。
SELECT companyname,fax
FROM suppliers
WHERE fax IS NULL
⑥邏輯運(yùn)算符(用于組合多個(gè)條件,簡(jiǎn)化查詢處理):NOT、AND和OR,優(yōu)先級(jí)從左到右依次降低。
1.4 ORDER BY子句
用ORDER BY子句對(duì)結(jié)果集中的行進(jìn)行升序(ASC)或降序(DESC)排列。
格式:ORDER BY {order_by_expression [ASC|DESC]} [,…n]
注意:不可以在ORDER BY子句中使用ntext、text或image類型的列。
例如,下面從數(shù)據(jù)庫(kù)“northwind”的 “products”表中檢索每個(gè)產(chǎn)品的產(chǎn)品標(biāo)識(shí)、產(chǎn)品名、類別和單價(jià)。先將結(jié)果集按照類別進(jìn)行升序排列,對(duì)于同一類別,再按照單價(jià)進(jìn)行降序排列。
SELECT productid,productname,categoryid,unitprice
FROM products
ORDER BY categoryid,unitprice DESC
2 聯(lián)合查詢
使用UNION子句的查詢稱為聯(lián)合查詢。它可以將兩個(gè)或更多個(gè)SELECT語句的返回結(jié)果組合到一個(gè)單個(gè)結(jié)果集中,該結(jié)果集包含了聯(lián)合查詢中所有查詢結(jié)果集中的全部行數(shù)據(jù)。
聯(lián)合查詢的語法格式如下:
select_statement
UNION [ALL] select_statement
[UNION [ALL] select_statement][…n]
其中,select_statement為待聯(lián)合的SELECT查詢語句。ALL選項(xiàng)表示將所有行都合并到結(jié)果集中,若缺省,則被聯(lián)合查詢結(jié)果集合中的重復(fù)行將只保留一行。
注意:①在用UNION子句查詢時(shí),查詢結(jié)果的列標(biāo)題為第一個(gè)查詢語句的列標(biāo)題。因此,必須在第一個(gè)SELECT語句中指定列標(biāo)題;②SQL Server要求所引用的表必須具有相似的數(shù)據(jù)類型、相同的列數(shù),且每個(gè)查詢中的選擇列表也必須具有相同的列順序;③如果希望結(jié)果集中的行按一定順序排列,則必須在最后一個(gè)有UNION操作符的語句中包含ORDER BY子句,以指定排序方式。
例如:從數(shù)據(jù)庫(kù)“經(jīng)銷商”的“顧客信息表”中,查詢姓王的顧客的姓名和家庭住址,并為其增加一個(gè)類型列TYPE,列的內(nèi)容為“顧客”;從“銷售人員表”中,查詢姓王的銷售人員的姓名和家庭住址,并增加一個(gè)列,列的內(nèi)容為“營(yíng)業(yè)員”;然后,將兩個(gè)查詢結(jié)果合并在一起。
SELECT姓名,家庭住址,顧客AS TYPE
FROM顧客信息表
WHERE姓名LIKE‘王%
UNION
SELECT姓名,家庭住址,營(yíng)業(yè)員
FROM銷售人員表
WHERE姓名LIKE ‘王%
3 連接查詢
連接操作可以同時(shí)查詢兩個(gè)或多個(gè)表中的數(shù)據(jù),所生成的結(jié)果集將多個(gè)表中的行和列合并在一起。
連接可以在SELECT 語句的FROM子句或WHERE子句中建立,建議在FROM子句中指定連接,這樣有助于將指定的連接條件與WHERE子句中的搜索條件區(qū)分開來。
SQL-92標(biāo)準(zhǔn)所定義的FROM子句的連接語法格式為:
FROM table_source1 join_type table_source 2
[ON (join_condition)]
其中,table_source1和table_source 2指定要查詢的表;join_type 指定所執(zhí)行的連接類型,可分為三類:內(nèi)連接(Inner Join)、外連接(Outer Join)、交叉連接(Cross Join);join_condition指定連接條件。
3.1 內(nèi)連接
內(nèi)連接通過比較兩個(gè)表共同擁有的列的值,把兩個(gè)表連接起來。SQL Server將只返回滿足連接條件的行。它是SQL Server默認(rèn)的連接方式。根據(jù)所使用的比較方式不同,內(nèi)連接又分為等值連接、自然連接和不等連接三種。
3.1.1 等值連接即在連接條件中使用“=”運(yùn)算符比較被連接列的列值,其查詢結(jié)果中列出被連接表中的所有列,包括重復(fù)列。
例如,列出數(shù)據(jù)庫(kù)“圖書管理系統(tǒng)”的“作者表”和“出版社信息表”中位于同一城市的作者和出版社信息。
SELECT *
FROM 作者表AS a INNER JOIN 出版社信息表AS b
ON a.籍貫=b.出版社所在城市
3.1.2 不等連接即在連接條件中使用除等于運(yùn)算符外的其它比較運(yùn)算符來比較被連接的列的列值。
3.1.3 自然連接即在連接條件中使用等于運(yùn)算符比較被連接列的列值,但它使用選擇列表指出查詢。
例:列出數(shù)據(jù)庫(kù)“圖書管理系統(tǒng)”的“作者表”和“出版社信息表”中位于同一城市的作者和出版社,并刪除重復(fù)列“籍貫”。
SELECT a.*,b.出版社編號(hào),b.出版社名稱,b.出版社電話
FROM 作者表AS a INNER JOIN 出版社信息表AS b
ON a.籍貫=b.出版社所在城市
3.2 外連接
若要?jiǎng)?chuàng)建一個(gè)查詢,以返回一個(gè)或多個(gè)表中的所有行(無論在另外的表中是否含有相匹配的行),則需要使用外連接。外連接有三種類型:左外連接(LEFT OUTER JOIN或LEFT JOIN)、右外連接(RIGHT OUTER JOIN或RIGHT JOIN)和完全外連接(FULL OUTER JOIN或FULL JOIN)。
例如,在數(shù)據(jù)庫(kù)“圖書管理系統(tǒng)”中,以在同一個(gè)城市的出版社和作者為條件,對(duì)“出版社信息表”和“作者表”進(jìn)行左外連接查詢。
SELECT a.姓名,a.性別,a.籍貫as 所在城市,b.出版社名稱
FROM 作者表as a LEFTJOIN 出版社信息表as b
ON a. 籍貫=b. 出版社所在城市
ORDER BY 姓名
在查詢結(jié)果窗口中,顯示左表中指定列的所有行和對(duì)應(yīng)連接列的所有行,在左表中沒有找到相匹配的右表的對(duì)應(yīng)位置填上NULL。
例如,在數(shù)據(jù)庫(kù)“圖書管理系統(tǒng)”中,以在同一個(gè)城市的出版社和作者為條件,對(duì)“出版社信息表”和“作者表”進(jìn)行完全外連接查詢。
SELECT a.姓名,a.性別,a.籍貫as 所在城市,b.出版社名稱
FROM 作者表as a FULLJOIN 出版社信息表as b
ON a.籍貫=b.出版社所在城市
ORDER BY 姓名
在查詢結(jié)果窗口中顯示相連接的兩個(gè)表的所有記錄,在沒有找到相匹配的位置上填上NULL。
3.3 交叉連接
交叉連接(CROSS JOIN)不帶WHERE子句,返回的是被連接的兩個(gè)表所有數(shù)據(jù)行的笛卡爾積,即返回到結(jié)果集中的數(shù)據(jù)行數(shù)等于第一個(gè)表中符合查詢條件的數(shù)據(jù)行數(shù)乘以第二個(gè)表中符合查詢條件的數(shù)據(jù)行數(shù)。
例如,下面將顯示數(shù)據(jù)庫(kù)“northwind”中“shippers”和“suppliers”表交叉連接后的結(jié)果集,以列出供應(yīng)商運(yùn)輸其產(chǎn)品的所有可能方式。
SELECT suppliers.companyname,shippers.companyname
FROM suppliers CROSS JOIN shippers
3.4 自連接
在連接查詢時(shí),當(dāng)table_source1和table_source 2是同一個(gè)表時(shí),即對(duì)同一個(gè)表進(jìn)行連接操作,則稱此連接為自連接。
例如,使用自連接在數(shù)據(jù)庫(kù)“圖書管理系統(tǒng)”的“作者表”中查找籍貫是“河北石家莊”的作者。
SELECT a.姓名,a.性別,b. 姓名,b.性別
FROM 作者表as a INNER JOIN作者表as b
ON a.籍貫=b.籍貫
WHERE a.籍貫=河北石家莊
ORDER BY 姓名
以上對(duì)于SELECT用法的介紹只是其最基本的,學(xué)生在學(xué)習(xí)時(shí),還應(yīng)多參考其它的一些例子,加強(qiáng)這方面的練習(xí),才能真正達(dá)到熟練掌握其用法的目的。