昨天我們終於打出了第一個 SQL 指令,現在我們來重新檢視一下昨天到底打了什麼。另外,往後我會使用 MySQL workbench 來操作,但是想要用 Command Line Client 操作也可以,兩個基本上是一樣的。
讓我們把昨天的指令拆開來看(SQL 用分號斷句,換行和空格基本上不影響語法!)
Select *
From city
Where name = "Taipei";
這裡可以很清楚的看到這個指令包含了三個部分:
我們先看中間那個區塊 From. From 讓使用者去告訴資料庫管理系統,我現在想要從哪一個關聯表內選出資料。在這裡我選擇的是 city 這個關聯表。
最後那個區塊,Where,做的是某些條件的篩選。在這裡我尋找的是關聯表 name 這個屬性(attribute)。
最一開始的 Select 是選取結果要顯示哪一些屬性,這裡給了 * 表示顯示全部表格中的欄位。細心的讀者可能有發現我故意從第二行開始解釋,不只是因為這樣比較容易理解 SQL 到底在寫什麼,更重要的是這個順序和資料庫管理系統運行的順序是一樣的。
所以如果我想要找的是台北的人口,就可以簡單的改動上面這個指令變成
Select Population
From City
Where name="Taipei";
如果有同步操作的讀者,可以試試看寫出可以查詢到:在國家關係表中,台灣的面積和人口數呢?(答案在最後面)
SQL 在執行的時候回傳的永遠是一個表格(即使向上面的結果一樣是個數字,他也是一個數字的表格),不可能出現多餘一個表格的狀態。對於剛剛簡單的 SQL 指令,我們可以來做一點變化:
Select name AS City_Name, population
From City
Where countrycode="TWN" and population > 500000;
這裡我在 Select 和 Where 分別做了一點更動。在 Select 的部分,先針對其中一個屬性 (Attribute) 做了命名上面的變動。記得既然 Select 只管顯示,他並沒有針對資料庫本身的綱要重新命名,只是對輸出的結果做了更改。
第二個改變在於在條件式 Where 的區塊,這次我使用了兩個條件: 這個城市要位在台灣並且人口大於五十萬人。結果就會像右邊那樣顯示出來。
其實在資料庫運作原理中,條件式 Where 在做的事情是,針對 From 所選取的關聯表中的每一個資料集合 (tuple) ,決定為真或為假。如果這一筆資料是真,那就顯示,不然就隱藏。這個想法可以幫助在編寫較為複雜的條件式。問自己,我需要什麼條件式才能夠過濾掉我不需要的資料。
關於條件式如果要窮舉的話可能可以把 30 天都寫完,所以我簡單在下面列舉幾個比較常見的語法,其餘的再煩請 Google 大神。
countrycode="TWN" OR countrycode = "USA"
就會回傳台灣或美國的城市。countryname like "%W_"
就用於尋找國家縮寫中,任何字串在前並且倒數第二個字元是 W
然後最後有任意的一個字元。<
, >
, <=
, >=
, <>
。最後這個要解釋一下 <>
表示否定,Not 的意思。接著要介紹兩個 SQL 指令。第一個是 Limit。Limit 這個指令用於當回傳或是符合搜尋條件的資料集合過多的時候,我們可以限制在螢幕上面顯示的資料集合數量。當我們在測試或者只是想要看到部分資料的時候就可以使用 Limit。例如
Select name AS City_Name, population, countrycode
From City
Where countrycode <> "TWN"
Limit 10;
要特別注意的事情是資料庫管理系統裡面資料集合是沒有順序的。也就是說,每次執行指令回傳的資料,在沒有預先定義的情況下,可能會以不同的順序呈現。同時 Limit 也有可能會回傳不同的子集 (Subset)。這也是為什麼我們可以用 Order By 在做調整。例如
Select name AS City_Name, population, countrycode
From City
Where countrycode = "TWN"
Order by population DESC
Limit 10;
就是用人口數由大到小排列之後取前 10 大的台灣城市。
再給一個小練習吧!這次我們要找的是在世界上,國家名稱裡有出現 an 兩個字,並且國家面積前 5 大的國家人口數。
除了剛剛我們做的限制或是排序,在 Select 的地方我們也可以針對選出來的資料做一些處理。
最簡單的就是統計運算。例如說,我們可以查詢全世界最多人口的城市來自於哪 20 個國家,而且這些國家不能重複,重複就遞補。
Select countrycode
From City
Order by population DESC
Limit 20;
原本的指令會出現重複的國家名稱! 這時候就可以利用 Distinct 來做過濾。
Select Distinct(countrycode)
From City
Order by population DESC
Limit 20;
當然也可以針對數字直接做修正,例如
Select name AS City_Name, population*1.2, countrycode
From City
Order by population DESC
Limit 5;
就可以針對結果的數值直接做變化。
其他相關的指令像是:Select Max(population) From City;
就可以找出最多人口城市的人數等等。
打到這裡,有沒有發現這篇文章有個東西我們還有有做任何調整?沒有錯就是 From 從哪裡這個指令。明天我們開始寫橫跨多個表格的 SQL。
--在國家關係表中,台灣的面積和人口數--
Select SurfaceArea, Population From country where name ="Taiwan";
--在世界上,國家名稱裡有出現an兩個字,並且國家面積前5大的國家名稱和人口數。--
Select name, surfaceArea From country
Where name Like "%an%" Order by population DESC Limit 5;