一、建立今天的練習環境
首先,建立資料庫連線和書籍資料表。為了讓程式可以獨立執行,今天會使用新的資料庫檔案。
import sqlite3
conn = sqlite3.connect("books_day24.db")
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS books (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
price REAL,
rating INTEGER
)
""")
conn.commit()
print("資料庫準備完成!")
接著新增一些練習資料。
books = [
("Python Basics", 350, 5),
("Web Scraping", 420, 4),
("Data Analysis", 500, 5),
("SQL Beginner", 280, 3),
("Machine Learning", 650, 4)
]
cursor.executemany("""
INSERT INTO books (title, price, rating)
VALUES (?, ?, ?)
""", books)
conn.commit()
print("練習資料新增完成!")
這裡需要注意,如果重複執行新增資料的程式,書籍會再次寫入資料庫。今天如果重跑整份程式,可以先重新建立資料庫連線前刪除舊檔,或使用其他方式清空測試資料,避免重複紀錄。
二、使用 WHERE 查詢特定資料
在資料庫中,如果只想取得符合條件的紀錄,可以使用 WHERE。
例如,查詢價格高於 400 元的書籍:
cursor.execute("""
SELECT title, price, rating
FROM books
WHERE price > ?
""", (400,))
rows = cursor.fetchall()
for row in rows:
print(row)
這段 SQL 的意思是:從 books 資料表中,找出價格大於 400 的書籍。
其中,? 是參數佔位符,而 (400,) 是傳入的參數。使用參數化查詢,可以避免直接將外部輸入拼接進 SQL 指令。
如果想查詢評分為 5 的書籍,可以修改條件:
cursor.execute("""
SELECT title, price, rating
FROM books
WHERE rating = ?
""", (5,))
for row in cursor.fetchall():
print(row)
WHERE 不只能判斷價格,也可以用來篩選評分、名稱或其他欄位。
三、使用 AND 和 OR 組合條件
有時候,一筆資料需要同時符合多個條件。
例如,我想找出價格高於 300 元,而且評分至少為 4 的書籍:
cursor.execute("""
SELECT title, price, rating
FROM books
WHERE price > ? AND rating >= ?
""", (300, 4))
for row in cursor.fetchall():
print(row)
AND 表示兩個條件都必須成立。
如果希望查詢價格低於 300 元,或評分為 5 的書籍,就可以使用 OR:
cursor.execute("""
SELECT title, price, rating
FROM books
WHERE price < ? OR rating = ?
""", (300, 5))
for row in cursor.fetchall():
print(row)
OR 表示只要其中一個條件成立,就可以符合查詢條件。
這種寫法很適合用在資料篩選,例如找出低價商品,或找出評價特別高的商品。
四、使用 UPDATE 修改資料
接下來,練習修改資料庫中已經存在的紀錄。
假設 Python Basics 這本書的價格從 350 元調整成 380 元,可以使用 UPDATE:
cursor.execute("""
UPDATE books
SET price = ?
WHERE title = ?
""", (380, "Python Basics"))
conn.commit()
print("書籍價格更新完成!")
這段程式包含兩個重要部分:
SET price = ?:指定要修改的欄位和值。
WHERE title = ?:指定要修改哪一筆或哪些紀錄。
執行完成後,可以再查詢一次,確認價格是否改變:
cursor.execute("""
SELECT title, price
FROM books
WHERE title = ?
""", ("Python Basics",))
print(cursor.fetchall())
特別注意: 執行 UPDATE 時,如果忘記加上 WHERE,就可能將整張資料表中所有書籍的價格都修改掉。
例如,以下指令會修改每一筆紀錄的價格:
UPDATE books
SET price = 380;
因此,在實際修改資料前,應該先使用 SELECT 確認條件會選到哪些紀錄。
五、使用 DELETE 刪除資料
如果資料庫中有不再需要的紀錄,也可以使用 DELETE。
例如,刪除 SQL Beginner 這本書:
cursor.execute("""
DELETE FROM books
WHERE title = ?
""", ("SQL Beginner",))
conn.commit()
print("指定書籍已刪除!")
接著查詢資料,確認該筆紀錄是否已經移除:
cursor.execute("""
SELECT * FROM books
""")
for row in cursor.fetchall():
print(row)
這裡同樣需要注意 WHERE 條件。
如果執行以下指令:
DELETE FROM books;
就會刪除 books 資料表中的所有紀錄。
資料表結構仍然存在,但資料會被清空。因此,刪除資料之前務必確認條件是否正確。
六、使用 ORDER BY 和 LIMIT 排序資料
除了查詢、修改和刪除,資料庫也能直接排序結果。
例如,找出價格最高的三本書:
cursor.execute("""
SELECT title, price
FROM books
ORDER BY price DESC
LIMIT 3
""")
for row in cursor.fetchall():
print(row)
這裡的 ORDER BY price DESC 表示依照價格由高到低排序,而 LIMIT 3 表示只取出前三筆結果。
如果想從最低價格開始排列,可以改成:
ORDER BY price ASC
這個功能和昨天使用 Pandas 的 sort_values() 很類似。差別在於,現在可以直接在資料庫中完成排序與篩選,不必先將所有資料讀進 Python。
七、使用 COUNT 和 GROUP BY 統計資料
資料庫也可以依照評分分類,計算每種評分有幾本書。
cursor.execute("""
SELECT rating, COUNT(*) AS book_count
FROM books
GROUP BY rating
ORDER BY rating DESC
""")
for row in cursor.fetchall():
print(row)
這段程式使用 GROUP BY rating,將相同評分的書籍分成一組,再用 COUNT(*) 計算每組的紀錄數量。
這和之前學過的 Pandas groupby() 有相似的概念。
如果資料量很大,直接在 SQL 中進行篩選和統計,也能減少需要傳回 Python 的資料量。
八、將查詢結果轉成 Pandas DataFrame
前幾天已經學會使用 Pandas 分析資料,現在可以把 SQLite 查詢結果交給 Pandas,結合兩者的功能。
import pandas as pd
df = pd.read_sql_query("""
SELECT title, price, rating
FROM books
WHERE price >= 300
ORDER BY price DESC
""", conn)
print(df)
這裡的 pd.read_sql_query() 可以直接執行 SQL,並將查詢結果轉換成 DataFrame。
因此,我可以先用 SQL 從資料庫篩選需要的資料,再使用 Pandas 進行更進一步的分析或製作圖表。
這種方式也很適合未來的書籍爬蟲專案:爬蟲負責取得資料、SQLite 負責儲存與查詢,而 Pandas 負責分析資料。
九、今天的實作流程整理
今天學到的 SQL 指令可以整理成以下表格:
SQL 指令
功能
使用情境
SELECT
查詢資料
查看書籍紀錄
WHERE
篩選條件
找出價格高於 400 的書
AND / OR
組合條件
同時判斷價格和評分
UPDATE
修改資料
更新書籍價格
DELETE
刪除資料
移除指定書籍
ORDER BY
排序資料
找出最貴的書
LIMIT
限制筆數
只取前三筆
GROUP BY
分組統計
統計各評分的書籍數量
最後,關閉資料庫連線:
conn.close()
print("資料庫連線已關閉!")
十、今天的學習心得
今天繼續學習 SQLite,練習了條件查詢、組合條件、更新和刪除資料,也學會使用排序和分組統計整理查詢結果。
我發現資料庫不只是用來保存資料,更重要的是能夠按照需求快速找到需要的紀錄,並在必要時進行修改。之前使用 Pandas 時,我通常會先讀取資料,再進行篩選和分析;現在則可以先透過 SQL 選出需要的資料,再交給 Pandas 處理。
接下來,我會繼續把爬蟲、資料清理和 SQLite 整合起來,讓書籍資料能夠從網頁取得、儲存到資料庫,再進行查詢和分析。