欄位命名
上一篇提到,SQL有內建的函數 aggregate functions,可以計算最大值 / 最小值 / 平均值 / 加總等。若我們執行該函數,所得的結果,會長什麼樣子呢?
SELECT MAX(budget), MAX(duration)
FROM films;
所得結果如下圖,原本的 films
是沒有自帶 max 欄名的資料,但因為我們執行了 MAX()
函數,所以 SQL 自動把所得結果的欄名命名為 max ;不過,因為兩筆資料都是執行 MAX()
函數,乍看之下難以區分(其實左邊是budget,右邊是duration)。
再看一個例子,上一篇說到,SQL 可以直接針對欄做加減:
SELECT (budget - gross)
FROM films;
所得結果如下,因為我們直接相減,並不是使用函數,所以這次的欄名什麼也沒有:
上面兩種情況,容易在分析資料的時候搞混數據,因此我們需要使用 AS
來命名。原本的命令式可以改寫成以下方式,表頭就出現啦!
SELECT MAX(budget) AS max_budget,
MAX(duration) AS max_duration
FROM films;SELECT (budget - gross) AS net_profit
FROM films;
利用 SQL 做初步數據分析
在此之前都只是篩選資料,接下來,我們可以針對 SQL 資料做一些簡單的計算及分析。
案例一:假設今天我們有一份叫做 people
的資料,這裡面包含了某個社區共一萬名住戶資訊,包含他們的姓名 name
、出生日期 birthdate
、死亡日期 deathdate
。我們試著計算此社區中「已死亡居民的比例」,並把結果的欄位名叫做 percentage_dead
:
SELECT (COUNT(deathdate) * 1.0 / COUNT(*)) * 100 AS percentage_dead
FROM people;
注意,若只用 (COUNT(deathdate) / COUNT(*)) * 100
,結果是0。因為 COUNT(deathdate) / COUNT(*)
這個計算式只會取相除後的整數,不含餘數!
案例二:假設有一份叫做 films
的資料,這裡面包含了四千多部電影的名字、上映年份、製作國家、電影長度、預算、票房…etc.等資訊。我們想要算出,此份資料中,最舊和最新的電影,差距了多少decades (十年) :
SELECT ( MAX(release_year) - MIN(release_year) ) / 10
AS number_of_decades
FROM films ;
排序 ORDER BY
在 SQL 中選取 / 計算的資料結果,可以依照使用者需求作排序,這時候要出動 ORDER BY
。若沒有定義,SQL 預設為升冪(由小到大,由 A 到 Z ):
SELECT title, release_year
FROM films
ORDER BY release_year;
若要改降冪,則在 ORDER BY
最後加上 DESC
SELECT title, release_year
FROM films
ORDER BY release_year DESC;
我們也可以使用複數個排序,但須注意順序很重要:
SELECT title, release_year, duration
FROM films
ORDER BY release_year, duration;
以下可以看到,電影會優先由 release_year
開始排序,若同一個年份中有2部以上的電影,才會依照 duration
長短排序。此處預設為升冪排序法,故年份及長度皆由小到大。
另外,還記得剛剛有說改為降冪排序法的關鍵字 DESC
,在使用複數排序時,也可以使用的:
SELECT title, release_year, duration
FROM films
ORDER BY release_year, duration DESC;
#以上命令,會依照升冪年份 & 降冪長度排序
SELECT title, release_year, duration
FROM films
ORDER BY release_year DESC, duration DESC;
#年份 & 長度都改為降冪
分類 GROUP BY
用以下例子說明GROUP BY 的使用時機與方式。
一樣使用剛剛的 films
的資料,我們想知道每年上映的電影有多少部?目前我們已知的方法其實可以做到(但比較繁瑣):
SELECT DISTINCT(release_year)
FROM films ;
#先搞清楚到底有幾個不同的年份SELECT COUNT(release_year) AS number_1997
FROM films
WHERE release_year=1997 ;SELECT COUNT(release_year) AS number_1998
FROM films
WHERE release_year=1998 ;SELECT COUNT(release_year) AS number_1999
FROM films
WHERE release_year=1999 ;...
...
...
若改使用 GROUP BY
,可簡化成以下方法:
SELECT release_year, count(*)
FROM films
GROUP BY release_year ;
除了數數量 COUNT(*)
,也可以計算平均值、最大值、最小值等。例如,我們想計算,每一年電影的平均預算是多少:
SELECT release_year AS year_category, AVG(budget) AS average_budgetFROM films
GROUP BY release_year ;
HAVING 用法
前面使用 WHERE
做條件式的時候,都是使用邏輯 (= < > 等等),要注意,不能在 WHERE
裡面搭配aggregate function否則會出現錯誤。
我們想篩選出,每年上映電影大於10部的年份,需使用 HAVING
條件式
SELECT release_year, COUNT(*) AS qty
FROM films
GROUP BY release_year
HAVING COUNT(*) > 10;
總複習
請篩選出以下資料:
filme
資料中,上映日期在1990年(不含) 以後,且平均製作預算高6千萬的每一年平均製作預算、平均獲利,且依照平均獲利由高而低排列:
SELECT release_year, AVG(budget) AS avg_budget, AVG(gross) AS avg_gross
FROM films
WHERE release_year > 1990
GROUP BY release_year
HAVING AVG(budget) > 60000000
ORGER BY AVG(gross) DESC;
請篩選出以下資料:
filme
資料中,總共製作10部電影(含)以上的國家,這些國家的平均製作預算及平均獲利。需依國家名(字母)排序,且只顯示前五個國家。
SELECT country, AVG(budget) AS avg_budget, AVG(gross) AS avg_gross, COUNT(*)
FROM films
GROUP BY country
HAVING count(*) > 10
ORDER BY country
LIMIT 5 ;