雖然LabVIEW號稱「圖控式程式語言」,但在資料庫的實際應用上,卻一定要使用SQL語法。許多網友因為對SQL語法不熟悉,所以在實際使用資料庫時,面臨進退兩難的窘境。所以在此整理SQL語法,希望對網友有幫助。
以下文章轉載自:http://www.1keydata.com/tw/ ,在此謝謝該網站的幫忙。
SQL指令 | 意義 |
---|---|
SELECT | 把資料從資料庫選出 |
DISTINCT | 從資料庫取出資料時,順便剔除掉重覆的資料 |
WHERE | 選擇性的抓資料 |
AND OR | 配合where,透過 AND 或是 OR 建構複雜的條件式。一個 SQL 語句中可以有無限多個簡單條件的存在。 |
IN | IN 這個指令可以讓我們依照一或數個不連續 (discrete) 的值的限制之內抓出資料庫中的值 |
BETWEEN | BETWEEN 則是讓我們可以運用一個範圍 (range) 內抓出資料庫中的值 |
LIKE | LIKE 能讓我們依據一個模式 (pattern) 來找出我們要的資料 |
ORDER BY | 將資料排列,可以由小到大或是由大到小 |
Functions | 對數字做一些運算,例如將它們總合起來,或是找出它們的平均值 |
COUNT | COUNT 讓我們能夠數出在表格中有多少筆資料被選出來 |
GROUP BY | 當我們選不只一個欄位,且其中至少一個欄位有包含函數的運用時,我們就需要用到 GROUP BY 這個指令 |
HAVING | 可以對函數產生的值來設定條件 |
ALIAS | alias (別名) 在 SQL 上,最常用到的別名有兩種:欄位別名及表格別名 |
Join | 內部連接 |
Outer Join | 外部連接 |
Subquery | 當我們在 WHERE 子句或 HAVING 子句中插入另一個 SQL 語句時,我們就有一個 subquery 的架構 |
Union | UNION 指令的目的是將兩個 SQL 語句的結果合併起來 |
Union All | UNION ALL 這個指令的目的也是要將兩個 SQL 語句的結果合併在一起。 UNION ALL 和 UNION 不同之處在於 UNION ALL 會將每一筆符合條件的資料都列出來,無論資料值有無重複 |
Intersect | UNION 基本上是一個 OR (如果這個值存在於第一句或是第二句,它就會被選出),而 INTERSECT 則比較像 AND (這個值要存在於第一句和第二句才會被選出)。 UNION 是聯集,而 INTERSECT 是交集 |
Minus | MINUS 指令是運用在兩個 SQL 語句上。它先找出第一個 SQL 語句所產生的結果,然後看這些結果有沒有在第二個 SQL 語句的結果中 |
表格處理 | 意義 |
---|---|
CREATE TABLE | 在資料庫中建立表格 |
DROP TABLE | 清除表格 |
TRUNCATE TABLE | 在這個指令之下,表格中的資料會完全消失,可是表格本身會繼續存在 |
INSERT INTO | 一次輸入一筆資料入表格 |
UPDATE | 需要修改表格中的資料 |
DELETE FROM | 直接由資料庫中去除一些資料 |
SQL SELECT
SQL 是用來做什麼的呢?一個最常用的方式是將資料從資料庫中的表格內選出。從這一句回答中,我們馬上可以看到兩個關鍵字: 從 (FROM) 資料庫中的表格內 選出 (SELECT) 。(表格是一個資料庫內的結構,它的目的是儲存資料。) 我們由這裡可以看到最基本的 SQL 架構:
SELECT “欄位名” FROM “表格名”
我們用以下的例子來看看實際上是怎麼用的。假設我們有以下這個表格:
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
Los Angeles | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
若要選出所有的店名 (store_Name),我們就打入:
SELECT store_name FROM Store_Information
結果:
store_name
Los Angeles
San Diego
Los Angeles
Boston
我們一次可以讀取好幾個欄位,也可以同時由好幾個表格中選資料。
SQL DISTINCT
SELECT 指令讓我們能夠讀取表格中一個或數個欄位的所有資料。這將把所有的資料都抓出,無論資料值有無重複。在資料處理中,我們會經常碰到需要找出表格內的不同資料值的情況。換句話說,我們需要知道這個表格/欄位內有哪些不同的值,而每個值出現的次數並不重要。這要如何達成呢?在 SQL 中,這是很容易做到的。我們只要在 SELECT 後加上一個 DISTINCT 就可以了。 DISTINCT 的語法如下:
SELECT DISTINCT “欄位名”
FROM “表格名”
舉例來說,若要在以下的表格, Store_Information ,找出所有不同的店名時,
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
Los Angeles | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們就打入,
SELECT DISTINCT store_name FROM Store_Information
結果:
store_name
Los Angeles
San Diego
Boston
SQL WHERE
我們並不一定每一次都要將表格內的資料都完全抓出。在許多時候,我們會需要選擇性地抓資料。就我們的例子來說,我們可能只要抓出營業額超過 $1,000 的資料。要做到這一點,我們就需要用到 WHERE 這個指令。這個指令的語法如下:
SELECT “欄位名”
FROM “表格名”
WHERE “條件”
若我們要由以下的表格抓出營業額超過 $1,000 的資料,
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
Los Angeles | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們就打入,
SELECT store_name
FROM Store_Information
WHERE Sales > 1000
結果:
store_name
Los Angeles
SQL AND OR
在 SQL WHERE 中,我們看到 WHERE 指令可以被用來由表格中有條件地選取資料。 這個條件可能是簡單的 (像 SQL WHERE 的例子),也可能是複雜的。複雜條件是由二或多個簡單條件透過 AND 或是 OR 的連接而成。一個 SQL 語句中可以有無限多個簡單條件的存在。
複雜條件的語法如下:
SELECT “欄位名”
FROM “表格名”
WHERE “簡單條件”
{[AND|OR] “簡單條件”}+
{}+ 代表{}之內的情況會發生一或多次。在這裡的意思就是 AND 加簡單條件及 OR 加簡單條件的情況可以發生一或多次。另外,我們可以用 () 來代表條件的先後次序。
舉例來說,我們若要在 Store_Information 表格中選出所有 Sales 高於 $1,000 或是 Sales 在 $500 及 $275 之間的資料的話,
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
San Francisco | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們就打入,
SELECT store_name
FROM Store_Information
WHERE Sales > 1000
OR (Sales < 500 AND Sales > 275)
結果:
store_name
Los Angeles
San Francisco
SQL IN
在 SQL 中,在兩個情況下會用到 IN 這個指令;這一頁將介紹其中之一──與 WHERE 有關的那一個情況。在這個用法下,我們事先已知道至少一個我們需要的值,而我們將這些知道的值都放入 IN 這個子句。 IN 指令的語法為下:
SELECT “欄位名”
FROM “表格名”
WHERE “欄位名” IN (‘值一’, ‘值二’, …)
在括弧內可以有一或多個值,而不同值之間由逗點分開。值可以是數目或是文字。若在括弧內只有一個值,那這個子句就等於
WHERE “欄位名” = ‘值一’
舉例來說,若我們要在 Store_Information 表格中找出所有含蓋 Los Angeles 或 San Diego 的資料,
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
San Francisco | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們就打入,
SELECT *
FROM Store_Information
WHERE store_name IN (‘Los Angeles’, ‘San Diego’)
結果:
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
SQL BETWEEN
IN 這個指令可以讓我們依照一或數個不連續 (discrete) 的值的限制之內抓出資料庫中的值,而 BETWEEN 則是讓我們可以運用一個範圍 (range) 內抓出資料庫中的值。 BETWEEN 這個子句的語法如下:
SELECT “欄位名”
FROM “表格名”
WHERE “欄位名” BETWEEN ‘值一’ AND ‘值二’
這將選出欄位值包含在值一及值二之間的每一筆資料。
舉例來說,若我們要由 Store_Information 表格中找出所有介於 January 6, 1999 及 January 10, 1999 中的資料,
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
San Francisco | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們就打入,
SELECT *
FROM Store_Information
WHERE Date BETWEEN ‘Jan-06-1999’ AND ‘Jan-10-1999’
請讀者注意:在不同的資料庫中,日期的儲存法可能會有所不同。在這裡我們選擇了其中一種儲存法。
結果:
store_name | Sales | Date |
---|---|---|
San Diego | $250 | Jan-07-1999 |
San Francisco | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
SQL LIKE
LIKE 是另一個在 WHERE 子句中會用到的指令。基本上, LIKE 能讓我們依據一個模式 (pattern) 來找出我們要的資料。相對來說,在運用 IN 的時候,我們完全地知道我們需要的條件;在運用 BETWEEN 的時候,我們則是列出一個範圍。 LIKE 的語法如下:
SELECT “欄位名”
FROM “表格名”
WHERE “欄位名” LIKE {模式}
{模式} 經常包括野卡 (wildcard). 以下是幾個例子:
- ‘A_Z’: 所有以 ‘A’ 起頭,另一個任何值的字原,且以 ‘Z’ 為結尾的字串。 ‘ABZ’ 和 ‘A2Z’ 都符合這一個模式,而 ‘AKKZ’ 並不符合 (因為在 A 和 Z 之間有兩個字原,而不是一個字原)。
- ‘ABC%’: 所有以 ‘ABC’ 起頭的字串。舉例來說,‘ABCD’ 和 ‘ABCABC’ 都符合這個模式。
- ‘%XYZ’: 所有以 ‘XYZ’ 結尾的字串。舉例來說,‘WXYZ’ 和 ‘ZZXYZ’ 都符合這個模式。 * ‘%AN%’: 所有含有 'AN’這個模式的字串。舉例來說, ‘LOS ANGELES’ 和 ‘SAN FRANCISCO’ 都符合這個模式。
我們將以上最後一個例子用在我們的 Store_Information 表格上:
Store_Information 表格
store_name | Sales | Date |
---|---|---|
LOS ANGELES | $1500 | Jan-05-1999 |
SAN DIEGO | $250 | Jan-07-1999 |
SAN FRANCISCO | $300 | Jan-08-1999 |
BOSTON | $700 | Jan-08-1999 |
我們就打入,
SELECT *
FROM Store_Information
WHERE store_name LIKE ‘%AN%’
結果:
store_name | Sales | Date |
---|---|---|
LOS ANGELES | $1500 | Jan-05-1999 |
SAN FRANCISCO | $300 | Jan-08-1999 |
SAN DIEGO | $250 | Jan-07-1999 |
SQL ORDER BY
到目前為止,我們已學到如何藉由 SELECT 及 WHERE 這兩個指令將資料由表格中抓出。不過我們尚未提到這些資料要如何排列。這其實是一個很重要的問題。事實上,我們經常需要能夠將抓出的資料做一個有系統的顯示。這可能是由小往大 (ascending) 或是由大往小(descending)。在這種情況下,我們就可以運用 ORDER BY 這個指令來達到我們的目的。
ORDER BY 的語法如下:
SELECT “欄位名”
FROM “表格名”
[WHERE “條件”]
ORDER BY “欄位名” [ASC, DESC]
[] 代表 WHERE 子句不是一定需要的。不過,如果 WHERE 子句存在的話,它是在 ORDER BY 子句之前。 ASC 代表結果會以由小往大的順序列出,而 DESC 代表結果會以由大往小的順序列出。如果兩者皆沒有被寫出的話,那我們就會用 ASC 。
我們可以照好幾個不同的欄位來排順序。在這個情況下, ORDER BY 子句的語法如下(假設有兩個欄位):
ORDER BY “欄位一” [ASC, DESC], “欄位二” [ASC, DESC]
若我們對這兩個欄位都選擇由小往大的話,那這個子句就會造成結果是依據 “欄位一” 由小往大排。若有好幾筆資料 “欄位一” 的值相等,那這幾筆資料就依據 “欄位二” 由小往大排。
舉例來說,若我們要依照 Sales 欄位的由大往小列出 Store_Information 表格中的資料,
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
San Francisco | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們就打入,
SELECT store_name, Sales, Date
FROM Store_Information
ORDER BY Sales DESC
結果:
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
Boston | $700 | Jan-08-1999 |
San Francisco | $300 | Jan-08-1999 |
San Diego | $250 | Jan-07-1999 |
在以上的例子中,我們用欄位名來指定排列順序的依據。除了欄位名外,我們也可以用欄位的順序 (依據 SQL 句中的順序)。在 SELECT 後的第一個欄位為 1,第二個欄位為 2,以此類推。在上面這個例子中,我們打以下這一句 SQL 可以達到完全一樣的效果:
SELECT store_name, Sales, Date
FROM Store_Information
ORDER BY 2 DESC
SQL Functions
既然資料庫中有許多資料都是已數字的型態存在,一個很重要的用途就是要能夠對這些數字做一些運算,例如將它們總合起來,或是找出它們的平均值。SQL 有提供一些這一類的函數。它們是:
- AVG (平均)
- COUNT (計數)
- MAX (最大值)
- MIN (最小值)
- SUM (總合)
運用函數的語法是:
SELECT “函數名”(“欄位名”)
FROM “表格名”
舉例來說,若我們要由我們的範例表格中求出 Sales 欄位的總合,
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
Los Angeles | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們就打入,
SELECT SUM(Sales) FROM Store_Information
結果:
SUM(Sales)
$2750
$2750 代表所有 Sales 欄位的總合: $1500 + $250 + $300 + $700.
除了函數的運用外,SQL 也可以做簡單的數學運算,例如加(+)和減(-)。對於文字類的資料,SQL 也有好幾個文字處理方面的函數,例如文字相連 (concatenation),文字修整 (trim),以及子字串 (substring)。不同的資料庫對這些函數有不同的語法,所以最好是參考您所用資料庫的資訊,來確定在那個資料庫中,這些函數是如何被運用的。
SQL COUNT
在 SQL Functions 有提到, COUNT 是函數之一。由於它的使用廣泛,我們在這裡特別提出來討論。基本上, COUNT 讓我們能夠數出在表格中有多少筆資料被選出來。它的語法是:
SELECT COUNT(“欄位名”)
FROM “表格名”
舉例來說,若我們要找出我們的範例表格中有幾筆 store_name 欄不是空白的資料時,
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
Los Angeles | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們就打入,
SELECT COUNT(store_name)
FROM Store_Information
WHERE store_name is not NULL
結果:
Count(store_name)
4
“is not NULL” 是 “這個欄位不是空白” 的意思。
COUNT 和 DISTINCT 經常被合起來使用,目的是找出表格中有多少筆不同的資料 (至於這些資料實際上是什麼並不重要)。舉例來說,如果我們要找出我們的表格中有多少個不同的 store_name,我們就打入,
SELECT COUNT(DISTINCT store_name)
FROM Store_Information
結果:
Count(DISTINCT store_name)
3
SQL GROUP BY
我們現在回到函數上。記得我們用 SUM 這個指令來算出所有的 Sales (營業額)吧!如果我們的需求變成是要算出每一間店 (store_name) 的營業額 (sales),那怎麼辦呢?在這個情況下,我們要做到兩件事:第一,我們對於 store_name 及 Sales 這兩個欄位都要選出。第二,我們需要確認所有的 sales 都要依照各個 store_name 來分開算。這個語法為:
SELECT “欄位1”, SUM(“欄位2”)
FROM “表格名”
GROUP BY “欄位1”
在我們的範例上,
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
Los Angeles | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們就打入,
SELECT store_name, SUM(Sales)
FROM Store_Information
GROUP BY store_name
結果:
store_name | SUM(Sales) |
---|---|
Los Angeles | $1800 |
San Diego | $250 |
Boston | $700 |
當我們選不只一個欄位,且其中至少一個欄位有包含函數的運用時,我們就需要用到 GROUP BY 這個指令。在這個情況下,我們需要確定我們有 GROUP BY 所有其他的欄位。換句話說,除了有包括函數的欄位外,我們都需要將其放在 GROUP BY 的子句中。
SQL HAVING
那我們如何對函數產生的值來設定條件呢?舉例來說,我們可能只需要知道哪些店的營業額有超過 $1,500。在這個情況下,我們不能使用 WHERE 的指令。那要怎麼辦呢?很幸運地,SQL 有提供一個 HAVING 的指令,而我們就可以用這個指令來達到這個目標。 HAVING 子句通常是在一個 SQL 句子的最後。一個含有 HAVING 子句的 SQL 並不一定要包含 GROUP BY 子句。 HAVING 的語法如下:
SELECT “欄位1”, SUM(“欄位2”)
FROM “表格名”
GROUP BY “欄位1”
HAVING (函數條件)
請讀者注意: GROUP BY 子句並不是一定需要的。
在我們 Store_Information 表格這個例子中,
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
Los Angeles | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們打入,
SELECT store_name, SUM(sales)
FROM Store_Information
GROUP BY store_name
HAVING SUM(sales) > 1500
結果:
store_name | SUM(Sales) |
---|---|
Los Angeles | $1800 |
SQL ALIAS
接下來,我們討論 alias (別名) 在 SQL 上的用處。最常用到的別名有兩種:欄位別名及表格別名。
簡單地來說,欄位別名的目的是為了讓 SQL 產生的結果易讀。在之前的例子中,每當我們有營業額總合時,欄位名都是 SUM (sales)。雖然在這個情況下沒有什麼問題,可是如果這個欄位不是一個簡單的總合,而是一個複雜的計算,那欄位名就沒有這麼易懂了。若我們用欄位別名的話,就可以確認結果中的欄位名是簡單易懂的。
第二種別名是表格別名。要給一個表格取一個別名,只要在 FROM 子句中的表格名後空一格,然後再列出要用的表格別名就可以了。這在我們要用 SQL 由數個不同的表格中獲取資料時是很方便的。這一點我們在之後談到連接 (join) 時會看到。
我們先來看一下欄位別名和表格別名的語法:
SELECT “表格別名”.“欄位1” “欄位別名”
FROM “表格名” “表格別名”
基本上,這兩種別名都是放在它們要替代的物件後面,而它們中間由一個空白分開。我們繼續使用 Store_Information 這個表格來做例子:
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
Los Angeles | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們用跟 SQL GROUP BY 那一頁一樣的例子。這裡的不同處是我們加上了欄位別名以及表格別名:
SELECT A1.store_name Store, SUM(A1.Sales) “Total Sales”
FROM Store_Information A1
GROUP BY A1.store_name
結果:
Store | Total Sales |
---|---|
Los Angeles | $1800 |
San Diego | $250 |
Boston | $700 |
在結果中,資料本身沒有不同。不同的是欄位的標題。這是運用欄位別名的結果。在第二個欄位上,原本我們的標題是 “Sum(Sales)”,而現在我們有一個很清楚的 “Total Sales”。很明顯地, “Total Sales” 能夠比 “Sum(Sales)” 更精確地闡述這個欄位的含意。用表格別名的好處在這裡並沒有顯現出來,不過這在 SQL Join 就會很清楚了。
SQL Join
現在我們介紹連接(join)的概念。要瞭解連接,我們需要用到許多我們之前已介紹過的指令。我們先假設我們有以下的兩個表格,
Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999
Geography 表格
region_name store_name
East Boston
East New York
West Los Angeles
West San Diego
而我們要知道每一區 (region_name) 的營業額 (sales)。 Geography 這個表格告訴我們每一區有哪些店,而 Store_Information 告訴我們每一個店的營業額。若我們要知道每一區的營業額,我們需要將這兩個不同表格中的資料串聯起來。當我們仔細瞭解這兩個表格後,我們會發現它們可經由一個相同的欄位,store_name,連接起來。我們先將 SQL 句列出,之後再討論每一個子句的意義:
SELECT A1.region_name REGION, SUM(A2.Sales) SALES
FROM Geography A1, Store_Information A2
WHERE A1.store_name = A2.store_name
GROUP BY A1.region_name
結果:
REGION | SALES |
---|---|
East | $700 |
West | $2050 |
在第一行中,我們告訴 SQL 去選出兩個欄位:第一個欄位是 Geography 表格中的 region_name 欄位 (我們取了一個別名叫做 REGION);第二個欄位是 Store_Information 表格中的 sales 欄位 (別名為 SALES)。請注意在這裡我們有用到表格別名: Geography 表格的別名是 A1, Store_Information 表格的別名是 A2。若我們沒有用表格別名的話,第一行就會變成
SELECT Geography.region_name REGION, SUM(Store_Information.Sales) SALES
很明顯地,這就複雜多了。在這裡我們可以看到表格別名的功用:它能讓 SQL 句容易被瞭解,尤其是這個 SQL 句含蓋好幾個不同的表格時。
接下來我們看第三行,就是 WHERE 子句。這是我們闡述連接條件的地方。在這裡,我們要確認 Geography 表格中 store_name 欄位的值與 Store_Information 表格中 store_name 欄位的值是相等的。這個 WHERE 子句是一個連接的靈魂人物,因為它的角色是確定兩個表格之間的連接是正確的。如果 WHERE 子句是錯誤的,我們就極可能得到一個笛卡兒連接 (Cartesian join)。笛卡兒連接會造成我們得到所有兩個表格每兩行之間所有可能的組合。在這個例子中,笛卡兒連接會讓我們得到 4 x 4 = 16 行的結果。
SQL Outer Join
之前我們看到的左連接 (left join),又稱內部連接 (inner join)。在這個情況下,要兩個表格內都有同樣的值,那一筆資料才會被選出。那如果我們想要列出一個表格中每一筆的資料,無論它的值在另一個表格中有沒有出現,那該怎麼辦呢?在這個時候,我們就需要用到 SQL OUTER JOIN (外部連接) 的指令。
外部連接的語法是依資料庫的不同而有所不同的。舉例來說,在 Oracle 上,我們會在 WHERE 子句中要選出所有資料的那個表格之後加上一個 “(+)” 來代表說這個表格中的所有資料我們都要。
假設我們有以下的兩個表格:
Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999
Geography 表格
region_name store_name
East Boston
East New York
West Los Angeles
West San Diego
我們需要知道每一間店的營業額。如果我們用一個普通的連接,我們將會漏失掉 'New York’這個店,因為它並不存在於 Store_Information 這個表格。所以,在這個情況下,我們需要用外部連接來串聯這兩個表格:
SELECT A1.store_name, SUM(A2.Sales) SALES
FROM Georgraphy A1, Store_Information A2
WHERE A1.store_name = A2.store_name (+)
GROUP BY A1.store_name
我們在這裡是使用了 Oracle 的外部連接語法。
結果:
store_name | SALES |
---|---|
Boston | $700 |
New York | |
Los Angeles | $1800 |
San Diego | $250 |
請注意: 當第二個表格沒有相對的資料時, SQL 會傳回 NULL 值。在這一個例子中, ‘New York’ 並不存在於 Store_Information 表格,所以它的 “SALES” 欄位是 NULL.
SQL Subquery
我們可以在一個 SQL 語句中放入另一個 SQL 語句。當我們在 WHERE 子句或 HAVING 子句中插入另一個 SQL 語句時,我們就有一個 subquery 的架構。 Subquery 的作用是什麼呢?第一,它可以被用來連接表格。另外,有的時候 subquery 是唯一能夠連接兩個表格的方式。
Subquery 的語法如下:
SELECT “欄位1”
FROM “表格”
WHERE “欄位2” [比較運算素]
(SELECT “欄位1”
FROM “表格”
WHERE [條件])
[比較運算素] 可以是相等的運算素,例如 =, >, <, >=, <=. 這也可以是一個對文字的運算素,例如 “LIKE.”
我們就用剛剛在闡述 SQL 連接時用過的例子:
Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999
Geography 表格
region_name store_name
East Boston
East New York
West Los Angeles
West San Diego
我們要運用 subquery 來找出所有在西部的店的營業額。我們可以用下面的 SQL 來達到我們的目的:
SELECT SUM(Sales) FROM Store_Information
WHERE Store_name IN
(SELECT store_name FROM Geography
WHERE region_name = ‘West’)
結果:
SUM(Sales)
2050
在這個例子中,我們並沒有直接將兩個表格連接起來,然後由此直接算出每一間西區店面的營業額。我們做的是先找出哪些店是在西區的,然後再算出這些店的營業額總共是多少。
SQL Union
UNION 指令的目的是將兩個 SQL 語句的結果合併起來。從這個角度來看, UNION 跟 JOIN 有些許類似,因為這兩個指令都可以由多個表格中擷取資料。 UNION 的一個限制是兩個 SQL 語句所產生的欄位需要是同樣的資料種類。另外,當我們用 UNION 這個指令時,我們只會看到不同的資料值 (類似 SELECT DISTINCT )。
UNION 的語法如下:
[SQL 語句 1]
UNION
[SQL 語句 2]
假設我們有以下的兩個表格,
Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999
Internet Sales 表格
Date Sales
Jan-07-1999 $250
Jan-10-1999 $535
Jan-11-1999 $320
Jan-12-1999 $750
而我們要找出來所有有營業額 (sales) 的日子。要達到這個目的,我們用以下的 SQL 語句:
SELECT Date FROM Store_Information
UNION
SELECT Date FROM Internet_Sales
結果:
Date
Jan-05-1999
Jan-07-1999
Jan-08-1999
Jan-10-1999
Jan-11-1999
Jan-12-1999
有一點值得注意的是,如果我們在任何一個 SQL 語句 (或是兩句都一起) 用 " SELECT DISTINCT Date " 的話,那我們會得到完全一樣的結果。
SQL Union All
UNION ALL 這個指令的目的也是要將兩個 SQL 語句的結果合併在一起。 UNION ALL 和 UNION 不同之處在於 UNION ALL 會將每一筆符合條件的資料都列出來,無論資料值有無重複。
UNION ALL 的語法如下:
[SQL 語句 1]
UNION ALL
[SQL 語句 2]
我們用和 SQL Union 同樣的例子來顯示出 UNION ALL 和 UNION 的不同。同樣假設我們有以下兩個表格,
Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999
Internet Sales 表格
Date Sales
Jan-07-1999 $250
Jan-10-1999 $535
Jan-11-1999 $320
Jan-12-1999 $750
而我們要找出有店面營業額以及網路營業額的日子。要達到這個目的,我們用以下的 SQL 語句:
SELECT Date FROM Store_Information
UNION ALL
SELECT Date FROM Internet_Sales
結果:
Date
Jan-05-1999
Jan-07-1999
Jan-08-1999
Jan-08-1999
Jan-07-1999
Jan-10-1999
Jan-11-1999
Jan-12-1999
SQL Intersect
和 UNION 指令類似, INTERSECT 也是對兩個 SQL 語句所產生的結果做處理的。不同的地方是, UNION 基本上是一個 OR (如果這個值存在於第一句或是第二句,它就會被選出),而 INTERSECT 則比較像 AND (這個值要存在於第一句和第二句才會被選出)。 UNION 是聯集,而 INTERSECT 是交集。
INTERSECT 的語法如下:
[SQL 語句 1]
INTERSECT
[SQL 語句 2]
假設我們有以下的兩個表格,
Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999
Internet Sales 表格
Date Sales
Jan-07-1999 $250
Jan-10-1999 $535
Jan-11-1999 $320
Jan-12-1999 $750
而我們要找出哪幾天有店面交易和網路交易。要達到這個目的,我們用以下的 SQL 語句:
SELECT Date FROM Store_Information
INTERSECT
SELECT Date FROM Internet_Sales
結果:
Date
Jan-07-1999
請注意,在 INTERSECT 指令下,不同的值只會被列出一次。
SQL Minus
MINUS 指令是運用在兩個 SQL 語句上。它先找出第一個 SQL 語句所產生的結果,然後看這些結果有沒有在第二個 SQL 語句的結果中。如果有的話,那這一筆資料就被去除,而不會在最後的結果中出現。如果第二個 SQL 語句所產生的結果並沒有存在於第一個 SQL 語句所產生的結果內,那這筆資料就被拋棄。
MINUS 的語法如下:
[SQL 語句 1]
MINUS
[SQL 語句 2]
我們繼續使用一樣的例子:
Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999
Internet Sales 表格
Date Sales
Jan-07-1999 $250
Jan-10-1999 $535
Jan-11-1999 $320
Jan-12-1999 $750
而我們要知道有哪幾天是有店面營業額而沒有網路營業額的。要達到這個目的,我們用以下的 SQL 語句:
SELECT Date FROM Store_Information
MINUS
SELECT Date FROM Internet_Sales
結果:
Date
Jan-05-1999
Jan-08-1999
“Jan-05-1999”, “Jan-07-1999”, and “Jan-08-1999” 是 " SELECT Date FROM Store_Information " 所產生的結果。在這裡面, “Jan-07-1999” 是存在於 " SELECT Date FROM Internet_Sales " 所產生的結果中。因此 “Jan-07-1999” 並不在最後的結果中。
請注意,在 MINUS 指令下,不同的值只會被列出一次。
SQL CREATE TABLE
表格是資料庫中儲存資料的基本架構。在絕大部份的情況下,資料庫廠商不可能知道您需要如何儲存您的資料,所以通常您會需要自己在資料庫中建立表格。雖然許多資料庫工具可以讓您在不需用到 SQL 的情況下建立表格,不過由於表格是一個最基本的架構,我們決定包括 CREATE TABLE 的語法在這個網站中。
在我們跳入 CREATE TABLE 的語法之前,我們最好先對表格這個東西有些多一點的瞭解。表格被分為欄位 (column) 及列位 (row)。每一列代表一筆資料,而每一欄代表一筆資料的一部份。舉例來說,如果我們有一個記載顧客資料的表格,那欄位就有可能包括姓、名、地址、城市、國家、生日‧‧‧等等。當我們對表格下定義時,我們需要註明欄位的標題,以及那個欄位的資料種類。
那,資料種類是什麼呢?資料可能是以許多不同的形式存在的。它可能是一個整數 (例如 1),、一個實數 (例如 0.55)、一個字串 (例如 ‘sql’)、一個日期/時間 (例如 ‘2000-JAN-25 03:22:22’)、或甚至是以二進法 (binary) 的狀態存在。當我們在對一個表格下定義時,我們需要對每一個欄位的資料種類下定義。 (例如 ‘姓’ 這個欄位的資料種類是 char(50)──代表這是一個 50 個字元的字串)。我們需要注意的一點是不同的資料庫有不同的資料種類,所以在對表格做出定義之前最好先參考一下資料庫本身的說明。
CREATE TABLE 的語法是:
CREATE TABLE “表格名”
(“欄位 1” “欄位 1 資料種類”,
“欄位 2” “欄位 2 資料種類”,
… )
若我們要建立我們上面提過的顧客表格,我們就打入以下的 SQL:
CREATE TABLE customer
(First_Name char(50),
Last_Name char(50),
Address char(50),
City char(50),
Country char(25),
Birth_Date date)
SQL DROP TABLE
有時候我們會決定我們需要從資料庫中清除一個表格。事實上,如果我們不能這樣做的話,那將會是一個很大的問題,因為資料庫管理師 (Database Administrator – DBA) 勢必無法對資料庫做有效率的管理。還好,SQL 有提供一個 DROP TABLE 的語法來讓我們清除表格。 DROP TABLE 的語法是:
DROP TABLE “表格名”
我們如果要清除在 SQL CREATE TABLE 中建立的顧客表格,我們就打入:
DROP TABLE customer .
SQL TRUNCATE TABLE
有時候我們會需要清除一個表格中的所有資料。要達到者個目的,一種方式是我們在 SQL DROP TABLE 看到的 DROP TABLE 指令。不過這樣整個表格就消失,而無法再被用了。另一種方式就是運用 TRUNCATE TABLE 的指令。在這個指令之下,表格中的資料會完全消失,可是表格本身會繼續存在。 TRUNCATE TABLE 的語法為下:
TRUNCATE TABLE “表格名”
所以,我們如果要清除在 SQL CREATE TABLE 那一頁建立的顧客表格之內的資料,我們就打入:
TRUNCATE TABLE customer .
SQL INSERT INTO
到目前為止,我們學到了將如何把資料由表格中取出。但是這些資料是如果進入這些表格的呢?這就是這一頁 ( INSERT INTO ) 和下一頁 ( UPDATE ) 要討論的。
基本上,我們有兩種作法可以將資料輸入表格中內。一種是一次輸入一筆,另一種是一次輸入好幾筆。我們先來看一次輸入一筆的方式。
依照慣例,我們先介紹語法。一次輸入一筆資料的語法如下:
INSERT INTO “表格名” (“欄位1”, “欄位2”, …)
VALUES (“值1”, “值2”, …)
假設我們有一個架構如下的表格:
Store_Information 表格
Column Name | Data Type |
---|---|
store_name | char(50) |
Sales | float |
Date | datetime |
而我們要加以下的這一筆資料進去這個表格:在 January 10, 1999,Los Angeles 店有 $900 的營業額。我們就打入以下的 SQL 語句:
INSERT INTO Store_Information (store_name, Sales, Date)
VALUES (‘Los Angeles’, 900, ‘Jan-10-1999’)
第二種 INSERT INTO 能夠讓我們一次輸入多筆的資料。跟上面剛的例子不同的是,現在我們要用 SELECT 指令來指明要輸入表格的資料。如果您想說,這是不是說資料是從另一個表格來的,那您就想對了。一次輸入多筆的資料的語法是:
INSERT INTO “表格1” (“欄位1”, “欄位2”, …)
SELECT “欄位3”, “欄位4”, …
FROM “表格2”
以上的語法是最基本的。這整句 SQL 也可以含有 WHERE 、 GROUP BY 、及 HAVING 等子句,以及表格連接及別名等等。
舉例來說,若我們想要將 1998 年的營業額資料放入 Store_Information 表格,而我們知道資料的來源是可以由 Sales_Information 表格取得的話,那我們就可以打入以下的 SQL:
INSERT INTO Store_Information (store_name, Sales, Date)
SELECT store_name, Sales, Date
FROM Sales_Information
WHERE Year(Date) = 1998
在這裡,我用了 SQL Server 中的函數來由日期中找出年。不同的資料庫會有不同的語法。舉個例來說,在 Oracle 上,您將會使用 WHERE to_char(date,‘yyyy’)=1998。
SQL UPDATE
我們有時候可能會需要修改表格中的資料。在這個時候,我們就需要用到 UPDATE 指令。這個指令的語法是:
UPDATE “表格名”
SET “欄位1” = [新值]
WHERE {條件}
最容易瞭解這個語法的方式是透過一個例子。假設我們有以下的表格:
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
Los Angeles | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
我們發現說 Los Angeles 在 01/08/1999 的營業額實際上是 $500,而不是表格中所儲存的 $300,因此我們用以下的 SQL 來修改那一筆資料:
UPDATE Store_Information
SET Sales = 500
WHERE store_name = “Los Angeles”
AND Date = “Jan-08-1999”
現在表格的內容變成:
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
Los Angeles | $500 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
在這個例子中,只有一筆資料符合 WHERE 子句中的條件。如果有多筆資料符合條件的話,每一筆符合條件的資料都會被修改的。
我們也可以同時修改好幾個欄位。這語法如下:
UPDATE TABLE “表格”
SET (“欄位1”, “欄位2”) = ([值1], [值2])
WHERE {條件}
SQL DELETE FROM
在某些情況下,我們會需要直接由資料庫中去除一些資料。這可以藉由 DELETE FROM 指令來達成。它的語法是:
DELETE FROM “表格名”
WHERE {條件}
以下我們用個實例說明。假設我們有以下這個表格:
Store_Information 表格
store_name | Sales | Date |
---|---|---|
Los Angeles | $1500 | Jan-05-1999 |
San Diego | $250 | Jan-07-1999 |
Los Angeles | $300 | Jan-08-1999 |
Boston | $700 | Jan-08-1999 |
而我們需要將有關 Los Angeles 的資料全部去除。在這裡我們可以用以下的 SQL 來達到這個目的:
DELETE FROM Store_Information
WHERE store_name = “Los Angeles”
現在表格的內容變成:
Store_Information 表格
store_name | Sales | Date |
---|---|---|
San Diego | $250 | Jan-07-1999 |
Boston | $700 | Jan-08-1999 |