SQL 是資料函式庫溝通的根本,無論是資料分析、軟體開發或資料倉管理,都繞不開它。這篇文章不只帶你認識 SELECT 和 FROM,更要教你 QUALIFY、ORDER BY 和 LIMIT 等進階用法,讓你寫 SQL 更得心應手。很多時候,我們需要一些臨時資料來測試或驗證,但又不想真的在資料函式庫裡建表。這時 SQL 的 VALUES 語法就很好用,可以直接在查詢中塞入資料,組成一個虛擬表,省時又方便。另外,WHERE 子句可以根據條件篩選資料,例如從 Nation 表中找出名稱以 “U” 開頭的國家,用 LIKE ‘U%’ 就可以搞定。更進一步,可以用 OR 或 AND 串接多個條件,精準撈出你要的資料。
在資料函式庫操作中,我們常需要對資料做分組統計,這時就要用到 GROUP BY。例如,想知道每個地區有多少國家,就可以用 GROUP BY 配合 COUNT() 函式,輕鬆算出每個地區的國家數量。但如果只想看特定條件的分組結果呢?這時 HAVING 子句就派上用場了。它跟 WHERE 子句很像,但 WHERE 是在分組前篩選,HAVING 是在分組後篩選。例如,只想看供應商數量超過 400 個的國家,就可以用 HAVING COUNT() > 400 來過濾。除了 WHERE 和 HAVING,還有一個更進階的篩選技巧:QUALIFY。它專門用於過濾視窗函式的結果,例如排名或累計總和。
假設要找出國家名稱長度排名前五的國家,就可以用 RANK() 函式搭配 QUALIFY 子句,程式碼簡潔又易懂。查詢結果的排序預設是亂的,如果要按照特定順序排列,就要用到 ORDER BY 子句。它可以根據一個或多個欄位排序,還可以指定升序或降序。例如,要按照供應商的帳戶餘額降序排列,就可以用 ORDER BY s_acctbal DESC。除了欄位名稱,ORDER BY 也支援用欄位位置排序,例如 ORDER BY 2 DESC 就等同於 ORDER BY s_acctbal DESC,因為 s_acctbal 是 SELECT 子句中的第二個欄位。
最後,LIMIT 子句可以限制查詢傳回的行數,在處理大型資料表或只想看部分結果時非常有用。例如,只想看帳戶餘額最高的 10 個供應商,就可以用 LIMIT 10。LIMIT 還可以搭配 OFFSET 子句使用,指定從哪一行開始傳回結果。例如,要看帳戶餘額最低的 10 個供應商,就可以用 LIMIT 10 OFFSET 7390,因為 Supplier 表有 7400 行,OFFSET 7390 表示從排序後的結果集的第 7391 行開始傳回 10 行。
SQL查詢入門:解構SELECT與FROM語法
SQL (Structured Query Language) 是與資料函式庫溝通的橋樑。無論是資料分析師、軟體工程師還是資料科學家,掌握SQL都是必備技能。本文玄貓將帶領大家從最基礎的SELECT和FROM子句開始,一步步瞭解SQL查詢的奧妙。
SELECT子句:資料的選擇器
SELECT子句是SQL查詢的核心,負責指定要從資料函式庫中檢索哪些資料。它可以簡單到只傳回一個字串:
-- 顯示歡迎訊息
SELECT 'Welcome to Snowflake SQL!';
內容解密 這段程式碼會直接顯示 “Welcome to Snowflake SQL!” 這個字串。在實際應用中,SELECT子句更有價值的是從資料表中選取特定的欄位。
假設我們有一個名為Nation的資料表,包含國家程式碼(N_NATIONKEY)、國家名稱(N_NAME)、區域程式碼(N_REGIONKEY)和備註(N_COMMENT)等欄位。
-- 檢視Nation資料表的結構
DESCRIBE TABLE nation;
內容解密
這段程式碼用於描述 nation 資料表的結構,包含欄位名稱、資料型別、是否允許 NULL 值等資訊。
若要從Nation資料表中選取國家程式碼、國家名稱和區域程式碼,可以使用以下查詢:
-- 從Nation資料表選取特定欄位
SELECT N_NATIONKEY, N_NAME, N_REGIONKEY
FROM nation;
內容解密
這段程式碼會從 nation 資料表中選取 N_NATIONKEY、N_NAME 和 N_REGIONKEY 三個欄位,並將結果以表格形式呈現。
SELECT子句的功能不僅限於選取資料表的欄位,它還可以包含:
- 常數 (Literals):例如數字99或字串’Hello, SQL!’。
- 運算式 (Expressions):例如
N_NATIONKEY * 100,對欄位進行數學運算。 - 內建函式 (Built-in Functions):例如
CONCAT(N_NATIONKEY, ' : ', N_NAME),將多個字串連線起來。 - 使用者定義函式 (User-Defined Functions):使用Java、Python或JavaScript等語言建立的自訂函式。
欄位別名:讓結果更易讀
有時候,查詢結果中的欄位名稱可能不太直觀。為了提高可讀性,可以使用欄位別名。
-- 使用欄位別名
SELECT 'Welcome to Snowflake SQL!' AS welcome_message,
5 * 3.1415927 AS circle_circumference,
DAYNAME(CURRENT_DATE()) AS day_of_week;
內容解密
這段程式碼使用 AS 關鍵字為查詢結果中的欄位指定別名,例如將 'Welcome to Snowflake SQL!' 的別名設為 welcome_message,讓結果更易於理解。
移除重複值:DISTINCT的妙用
在某些情況下,查詢結果可能包含重複的值。若要只取得唯一的值,可以使用DISTINCT關鍵字。
-- 檢視Nation資料表的區域程式碼
SELECT N_REGIONKEY FROM nation;
-- 移除重複的區域程式碼
SELECT DISTINCT N_REGIONKEY FROM nation;
內容解密
第一段程式碼會顯示 nation 資料表中所有 N_REGIONKEY 的值,可能包含重複項。第二段程式碼則使用 DISTINCT 關鍵字,只顯示不重複的 N_REGIONKEY 值。
FROM子句:指定資料來源
FROM子句用於指定查詢的資料來源,可以是單個資料表,也可以是多個資料表。
-- 從Nation資料表選取資料
SELECT N_NATIONKEY, N_NAME AS nation_name
FROM nation;
內容解密
這段程式碼從 nation 資料表中選取 N_NATIONKEY 和 N_NAME 欄位,並將 N_NAME 的別名設為 nation_name。
當FROM子句包含多個資料表時,需要使用JOIN子句來指定資料表之間的關聯方式。例如,若要從Nation資料表取得國家程式碼和國家名稱,並從Region資料表取得區網域名稱,可以使用以下查詢:
-- 連線Nation和Region資料表
SELECT N_NATIONKEY, N_NAME AS nation_name,
R_NAME AS region_name
FROM nation
JOIN region ON nation.N_REGIONKEY = region.R_REGIONKEY;
內容解密
這段程式碼使用 JOIN 子句將 nation 和 region 資料表連線起來,連線條件是 nation.N_REGIONKEY = region.R_REGIONKEY,表示 nation 資料表的 N_REGIONKEY 欄位和 region 資料表的 R_REGIONKEY 欄位值相等時,將兩筆資料合併成一筆。
VALUES子句:動態產生資料集
除了從資料表檢索資料外,Snowflake還允許使用VALUES子句動態產生資料集。這在建立小型測試資料集時非常有用。
-- 使用VALUES子句建立資料集
SELECT *
FROM (VALUES (1, 'Apple'), (2, 'Banana'), (3, 'Cherry')) AS fruits (id, name);
內容解密
這段程式碼使用 VALUES 子句建立一個包含三筆資料的資料集,每筆資料包含 id 和 name 兩個欄位。AS fruits (id, name) 用於指定資料集的名稱和欄位名稱。
玄貓結語
SELECT和FROM子句是SQL查詢的基礎,掌握它們是學習更複雜SQL語法的根本。透過本文的介紹,希望能幫助讀者更深入地理解SQL查詢的原理和應用。玄貓建議多加練習,才能真正掌握SQL這項強大的工具。
SQL查詢語法:玄貓帶你入門資料函式庫操作
SQL (Structured Query Language) 是資料函式庫操作的根本。無論你是資料科學家、軟體工程師,還是資料倉管理員,都必須熟悉 SQL 語法。今天,玄貓就帶大家快速入門 SQL 查詢,讓你輕鬆駕馭資料函式庫。
從虛擬表開始:SQL Values 的妙用
有時候,我們需要建立一個臨時的資料表來進行查詢,但又不想真的在資料函式庫中建立一個表。這時候,SQL 的 VALUES 語法就派上用場了。
舉例來說,如果你的資料函式庫裡沒有包含月份名稱和數字對應的表格,你可以用以下查詢建立一個:
SELECT *
FROM (VALUES
('JAN', 1),
('FEB', 2),
('MAR', 3),
('APR', 4),
('MAY', 5),
('JUN', 6),
('JUL', 7),
('AUG', 8),
('SEP', 9),
('OCT', 10),
('NOV', 11),
('DEC', 12)
) AS months (month_name, month_num);
內容解密
- 這段程式碼會建立一個名為
months的虛擬表,其中包含month_name和month_num兩個欄位。 VALUES語法允許你直接在查詢中插入資料列,而不需要先建立實際的資料表。AS months (month_name, month_num)定義了虛擬表的名稱和欄位名稱。
玄貓認為,VALUES 語法在快速建立測試資料或進行臨時查詢時非常有用。
Where 條件式:精準篩選資料
在資料函式庫中,我們常常需要根據特定條件篩選資料。WHERE 條件式就是用來實作這個功能的。
假設我們想要從 nation 資料表中找出所有國家名稱以 “U” 開頭的國家,可以使用以下查詢:
SELECT n_name
FROM nation
WHERE n_name LIKE 'U%';
內容解密
WHERE n_name LIKE 'U%'表示篩選n_name欄位,只留下以 “U” 開頭的資料列。LIKE運算元用於模糊比對,%符號代表任意字元。
如果我們想要找出所有國家名稱以 “U” 或 “A” 開頭的國家,可以使用 OR 運算元:
SELECT n_name
FROM nation
WHERE n_name LIKE 'U%'
OR n_name LIKE 'A%';
玄貓提醒,WHERE 條件式可以包含多個條件,並使用 AND 或 OR 運算元組合這些條件。
Group By:資料分組的藝術
GROUP BY 條件式用於將資料表中的資料列按照一個或多個欄位進行分組。這在報表和資料分析中非常常見。
例如,我們想要計算 nation 資料表中,每個地區 (region) 有多少個國家,可以使用以下查詢:
SELECT r_name AS region_name,
COUNT(*) AS number_of_countries
FROM nation
JOIN region ON nation.n_regionkey = region.r_regionkey
GROUP BY r_name;
內容解密
JOIN條件式用於將nation和region兩個資料表連線起來,ON nation.n_regionkey = region.r_regionkey指定了連線的條件。GROUP BY r_name表示按照r_name欄位進行分組。COUNT(*)函式用於計算每個分組中的資料列數量。
玄貓建議,GROUP BY 條件式通常與聚合函式(如 COUNT(), SUM(), AVG(), MAX(), MIN())一起使用,以計算每個分組的統計資訊。
Having:分組後的篩選
HAVING 條件式用於在 GROUP BY 分組後,根據分組的結果進行篩選。這與 WHERE 條件式不同,WHERE 條件式是在分組前進行篩選。
為了說明 HAVING 條件式的用法,我們假設有一個 supplier 資料表,其中包含供應商的資訊,包括供應商的國家程式碼 s_nationkey。
以下查詢計算每個國家有多少個供應商:
SELECT n_name AS nation_name,
COUNT(*) AS number_of_suppliers
FROM supplier
JOIN nation ON supplier.s_nationkey = nation.n_nationkey
GROUP BY n_name;
如果我們只想找出供應商數量超過 400 個的國家,可以使用 HAVING 條件式:
SELECT n_name AS nation_name,
COUNT(*) AS number_of_suppliers
FROM supplier
JOIN nation ON supplier.s_nationkey = nation.n_nationkey
GROUP BY n_name
HAVING COUNT(*) > 400;
內容解密
HAVING COUNT(*) > 400表示只留下供應商數量大於 400 的分組。
玄貓提醒,WHERE 條件式在分組前篩選資料列,而 HAVING 條件式在分組後篩選分組。
總結來說,SQL 查詢語法是資料函式庫操作的基礎。透過 VALUES 建立虛擬表,利用 WHERE 條件式精準篩選資料,使用 GROUP BY 進行資料分組,並用 HAVING 條件式篩選分組結果,你可以輕鬆駕馭資料函式庫,從中提取有用的資訊。
SQL進階篩選:QUALIFY語法的妙用
在資料函式庫查詢中,WHERE和HAVING是用於篩選資料的常見語法。但對於根據視窗函式(Window Function)結果的篩選,QUALIFY提供更簡潔的解決方案。QUALIFY專門用於過濾視窗函式的結果,例如排名或累計總和等。
以下玄貓將會探討QUALIFY子句,並展示如何使用它來簡化查詢,以及它與WHERE和HAVING的不同之處。
利用RANK()函式與QUALIFY子句進行排名篩選
假設我們想根據國家名稱的長度對Nation表中的國家進行排名,並篩選出排名前五的國家。可以使用RANK()視窗函式和QUALIFY子句來實作:
SELECT
n_name,
RANK() OVER (ORDER BY LENGTH(n_name) DESC) AS length_rank
FROM
nation
QUALIFY length_rank <= 5;
這個查詢首先使用RANK() OVER (ORDER BY LENGTH(n_name) DESC)計算每個國家名稱長度的排名。QUALIFY length_rank <= 5子句接著篩選出排名小於等於5的國家。
QUALIFY、WHERE、HAVING的區別
WHERE:在分組前篩選行資料。HAVING:在分組後篩選群組資料。QUALIFY:在視窗函式計算後篩選行資料。
QUALIFY使得在視窗函式的結果上進行篩選變得更加直觀和簡潔。
資料排序的藝術:ORDER BY子句
在SQL查詢中,結果集的排序預設是沒有特定順序的。若要按照特定順序(如字母順序、數值大小或時間先後)排列結果,可以使用ORDER BY子句。
基本語法
ORDER BY子句可以包含SELECT子句中的一個或多個元素,並可透過名稱或位置參照它們。
SELECT column1, column2
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC];
ASC:升序(預設)。DESC:降序。
例項解析:依供應商帳戶餘額排序
假設我們希望按照供應商的帳戶餘額(s_acctbal)降序排列Supplier表中的供應商名稱(s_name)和帳戶餘額。以下是實作此目標的SQL查詢:
SELECT s_name, s_acctbal
FROM supplier
ORDER BY s_acctbal DESC;
此查詢將結果集按照s_acctbal欄位的值從大到小排列。
依欄位位置排序
除了使用欄位名稱,還可以ORDER BY子句中使用欄位在SELECT子句中的位置來指定排序依據。
SELECT s_name, s_acctbal
FROM supplier
ORDER BY 2 DESC;
在這個例子中,ORDER BY 2 DESC與ORDER BY s_acctbal DESC的效果相同,因為s_acctbal是SELECT子句中的第二個欄位。
LIMIT子句:控制結果集的範圍
LIMIT子句允許指定查詢傳回的行數,從而控制結果集的大小。這在處理大型資料表或只需要檢視部分結果時非常有用。
基本語法
SELECT column1, column2
FROM table_name
ORDER BY column1
LIMIT row_count [OFFSET offset];
row_count:指定傳回的最大行數。OFFSET offset:指定從哪一行開始傳回結果(可選)。
例項解析:限制結果集大小
若要從Supplier表中檢索帳戶餘額最高的10個供應商,可以使用以下查詢:
SELECT s_name, s_acctbal
FROM supplier
ORDER BY s_acctbal DESC
LIMIT 10;
此查詢首先按照s_acctbal降序排列所有供應商,然後傳回前10行。
使用OFFSET子句
OFFSET子句允許從結果集的特定位置開始傳回行。例如,若要檢索帳戶餘額最低的10個供應商,可以使用以下查詢:
SELECT s_name, s_acctbal
FROM supplier
ORDER BY s_acctbal DESC
LIMIT 10 OFFSET 7390;
由於Supplier表有7400行,OFFSET 7390表示從排序後的結果集的第7391行開始傳回10行,即最後10行。
ORDER BY和LIMIT子句是SQL中非常實用的工具,可幫助更好地控制和管理查詢結果。
總之,QUALIFY、ORDER BY和LIMIT子句為SQL查詢提供了強大的靈活性和控制能力,使得資料分析和處理變得更加高效。