SELECT語句
SELECT語句可以從一個或多個表中選取特定的行和列。因為查詢和檢索數(shù)據(jù)是數(shù)據(jù)庫管理中最重要的功能,所以SELECT語句在SQL中是工作量最大的部分。實際上,僅僅是訪問數(shù)據(jù)庫來分析數(shù)據(jù)并生成報表的人可以對其他SQL語句一竅不通。 SELECT語句的結(jié)果通常是生成另外一個表。在執(zhí)行過程中系統(tǒng)根據(jù)用戶的標準從數(shù)據(jù)庫中選出匹配的行和列,并將結(jié)果放到臨時的表中。在直接SQL(direct SQL)中,它將結(jié)果顯示在終端的顯示屏上,或者將結(jié)果送到打印機或文件中。也可以結(jié)合其他SQL語句來將結(jié)果放到一個已知名稱的表中。 SELECT語句功能強大。雖然表面上看來它只用來完成本文第一部分中提到的關(guān)系代數(shù)運算“選擇”(或稱“限制”),但實際上它也可以完成其他兩種關(guān)系運算—“投影”和“連接”,SELECT語句還可以完成聚合計算并對數(shù)據(jù)進行排序。 SELECT語句最簡單的語法如下: SELECT columns FROM tables; 當我們以這種形式執(zhí)行一條SELECT語句時,系統(tǒng)返回由所選擇的列以及用戶選擇的表中所有指定的行組成的一個結(jié)果表。這就是實現(xiàn)關(guān)系投影運算的一個形式。 讓我們看一下使用圖1中EMPLOYEES表的一些例子(這個表是我們以后所有SELECT語句實例都要使用的。而我們在圖2和圖3中給出了查詢的實際結(jié)果。我們將在其他的例子中使用這些結(jié)果)。 假設(shè)你想查看雇員工作部門的列表。那下面就是你所需要編寫的SQL查詢: SELECT BRANCH_OFFICE FROM EMPLOYEES; 以上SELECT語句的執(zhí)行將產(chǎn)生如圖2中表2所示的結(jié)果。 由于我們在SELECT語句中只指定了一個列,所以我們的結(jié)果表中也只有一個列。注意結(jié)果表中具有重復(fù)的行,這是因為有多個雇員在同一部門工作(記住SQL從所選的所有行中將值返回)。要消除結(jié)果中的重復(fù)行,只要在SELECT語句中加上DISTINCT子句: SELECT DISTINCT BRANCH_OFFICE FROM EMPLOYEES; 這次查詢的結(jié)果如表3所示。 現(xiàn)在已經(jīng)消除了重復(fù)的行,但結(jié)果并不是按照順序排列的。如果你希望以字母表順序?qū)⒔Y(jié)果列出又該怎么做呢?只要使用ORDER BY子句就可以按照升序或降序來排列結(jié)果: SELECT DISTINCT BRANCH_OFFICE FROM EMPLOYEES ORDER BY BRANCH_OFFICE ASC; 這一查詢的結(jié)果如表4所示。請注意在ORDER BY之后是如何放置列名BRANCH _OFFICE的,這就是我們想要對其進行排序的列。為什么即使是結(jié)果表中只有一個列時我們也必須指出列名呢?這是因為我們還能夠按照表中其他列進行排序,即使它們并不顯示出來。列名BRANCH_ OFFICE之后的關(guān)鍵字ASC表示按照升序排列。如果你希望以降序排列,那么可以用關(guān)鍵字DESC。 同樣我們應(yīng)該指出ORDER BY子句只將臨時表中的結(jié)果進行排序;并不影響原來的表。 假設(shè)我們希望得到按部門排序并從工資最高的雇員到工資最低的雇員排列的列表。除了工資括號中我們還希望看到按照聘用時間從最近聘用的雇員開始列出的列表。以下是你將要用到的語句: SELECT BRANCH_OFFICE,FIRST_NAME, LAST_NAME,SALARY,HIRE_DATE FROM EMPLOYEES ORDER BY SALARY DESC, HIRE_DATE DESC; 這里我們進行了多列的選擇和排序。排序的優(yōu)先級由語句中的列名順序所決定。SQL將先對列出的第一個列進行排序。如果在第一個列中出現(xiàn)了重復(fù)的行時,這些行將被按照第二列進行排序,如果在第二列中又出現(xiàn)了重復(fù)的行時,這些行又將被按照第三列進行排序……如此類推。這次查詢的結(jié)果如表5所示。 將一個很長的表中的所有列名寫出來是一件相當麻煩的事,所以SQL允許在選擇表中所有的列時使用*號: SELECT * FROM EMPLOYEES; 這次查詢返回整個EMPLOYEES表,如表1所示。 下面我們對開始時給出的SELECT語句的語法進行一下更新(豎直線表示一個可選項,允許在其中選擇一項。): SELECT [DISTINCT] (column [{, columns}])| * FROM table [ {, table}] [ORDER BY column [ASC] | DESC [ {, column [ASC] | DESC }]]; NULL和三值邏輯 在SQL中NULL是一個復(fù)雜的話題,關(guān)于NULL的詳細描述更適合于在SQL的高級教程而不是現(xiàn)在的入門教程中進行介紹。但由于NULL需要進行特殊處理,并且你也很可能會遇到它,所以我們還是簡略地進行一下說明。 首先,在斷言中進行NULL判斷時需要特殊的語法。例如,如果用戶需要顯示所有年薪未知的職員的全部信息,用戶可以使用如下SELECT語句: SELECT * FROM EMPLOYEES WHERE SALARY IS NULL; 相反,如果用戶需要所有已知年薪數(shù)據(jù)的職員的信息,你可以使用以下語句: SELECT * FROM EMPLOYEES WHERE SALARY IS NOT NULL; 請注意我們在列名之后使用了關(guān)鍵字IS NULL或IS NOT NULL,而不是標準的比較形式:COLUMN = NULL、COLUMN <> NULL或是邏輯操作符NOT(NULL)。 這種形式相當簡單。但當你不明確地測試NULL(而它們確實存在)時,事情會變得很混亂。 例如,回過頭來看我們圖1中的EM-PLOYEES表,可以看到Indiana Jones的工薪等級或年薪值都是未知的。這兩個列都包含NULL??梢韵胂筮\行如下的查詢: SELECT * FROM EMPLOYEES WHERE GRADE <= SALARY; 此時,Indiana Jones應(yīng)該出現(xiàn)在結(jié)果表中。因為NULL都是相等的,所以可以想象它們是能夠通過GRADE小于等于SALARY的檢查的。這其實是一個毫無疑義的查詢,但是并沒有關(guān)系。SQL允許進行這樣的比較,只要兩個列都是數(shù)字類型的。然而,Indiana Jones并沒有出現(xiàn)在查詢的結(jié)果中,為什么? 正如我們早先提到過的,NULL表示未知的值(而不是象某些人所想象的那樣表示一個為NULL的值)。對于SQL來說意味著這個值是未知的,而只要這個值為未知,就不能將其與其他值比較(即使其他值也是NULL)。所以SQL允許除了在true 和false之外還有第三種類型的真值,稱之為“非確定”(unknown)值。 如果比較的兩邊都是NULL,整個斷言就被認為是非確定的。將一個非確定斷言取反或使用AND或OR與其他斷言進行合并之后,其結(jié)果仍是非確定的。由于結(jié)果表中只包括斷言值為“真”的行,所以NULL不可能滿足該檢查。從而需要使用特殊的操作符IS NULL和IS NOT NULL。 UPDATE語句 UPDATE語句允許用戶在已知的表中對現(xiàn)有的行進行修改。 例如,我們剛剛發(fā)現(xiàn)Indiana Jones的等級為16,工資為$40,000.00,我們可以通過下面的SQL語句對數(shù)據(jù)庫進行更新(并清除那些煩人的NULL)。 UPDATE EMPLOYEES SET GRADE = 16, SALARY = 40000 WHERE FIRST_NAME = 'Indiana' AND LAST_NAME = 'Jones'; 上面的例子說明了一個單行更新,但是UPDATE語句可以對多行進行操作。滿足WHERE條件的所有行都將被更新。如果,你想讓Boston辦事處中的所有職員搬到New York,你可以使用如下語句: UPDATE EMPLOYEES SET BRANCH_OFFICE = 'New York' WHERE BRANCH_OFFICE = 'Boston'; 如果忽略WHERE子句,表中所有行中的部門值都將被更新為'New York'。 UPDATE語句的語法流圖如下面所示: UPDATE table SET column = value [{, column = value}] [ WHERE predicate [ { logical-connector predicate}]]; DELETE語句 DELETE語句用來刪除已知表中的行。如同UPDATE語句中一樣,所有滿足WHERE子句中條件的行都將被刪除。由于SQL中沒有UNDO語句或是“你確認刪除嗎?”之類的警告,在執(zhí)行這條語句時千萬要小心。如果決定取消Los Angeles辦事處并解雇辦事處的所有職員,這一卑鄙的工作可以由以下這條語句來實現(xiàn): DELETE FROM EMPLOYEES WHERE BRANCH_OFFICE = 'Los Angeles'; 如同UPDATE語句中一樣,省略WHERE子句將使得操作施加到表中所有的行。 DELETE語句的語法流圖如下面所示: DELETE FROM table [WHERE predicate [ { logical-connector predicate} ] ]; 現(xiàn)在我們完成了數(shù)據(jù)操作語言(DML)的主要語句的介紹。我們并沒有對SQL能完成的所有功能進行說明。SQL還提供了許多的功能,如求平均值、求和以及其他對表中數(shù)據(jù)的計算,此外SQL還能完成從多個表中進行查詢(多表查詢,或稱之為連接)的工作。這種語言還允許你使用GRANT和REVOKE命令控制使用者的數(shù)據(jù)訪問權(quán)限 附.end |
|
來自: 輕風書屋閣 > 《技術(shù)論壇》