本文承接基礎入門,深入講解多表聯結(內連接、外連接、自連接、多表連接)與視圖的創建、使用、管理,所有示例基於經典樣本數據庫,含實際輸出驗證。
將數據按業務拆分到多表(如產品表、供應商表、訂單表),通過**外鍵**建立關聯,查詢時用 JOIN 重組。避免冗餘、保證一致性、節省空間。
SELECT vend_name, prod_name, prod_price
FROM vendors, products
WHERE vendors.vend_id = products.vend_id
ORDER BY vend_name, prod_name;
SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id = products.vend_id;
笛卡爾積警示:無連接條件時,結果行數 = 表1行數 × 表2行數,極其危險。
SELECT prod_name, vend_name, prod_price, quantity
FROM orderitems, products, vendors
WHERE products.vend_id = vendors.vend_id
AND orderitems.prod_id = products.prod_id
AND order_num = 20005;
SELECT prod_name, vend_name, prod_price, quantity
FROM orderitems AS o, products AS p, vendors AS v
WHERE p.vend_id = v.vend_id
AND o.prod_id = p.prod_id
AND o.order_num = 20005;
別名不返回客戶端,僅簡化 SQL 撰寫。
場景:查詢生產某產品(ID=DTNTR)的供應商的其他產品。
SELECT vend_id, prod_id, prod_name
FROM products
WHERE vend_id IN (
SELECT vend_id FROM products WHERE prod_id = 'DTNTR'
);
SELECT p1.vend_id, p1.prod_id, p1.prod_name
FROM products AS p1, products AS p2
WHERE p1.vend_id = p2.vend_id
AND p2.prod_id = 'DTNTR';
自聯結避免子查詢,優化器更易生成高效執行計劃。
SELECT customers.cust_id, cust_name, orders.order_num
FROM customers LEFT OUTER JOIN orders
ON customers.cust_id = orders.cust_id;
結果:無訂單客戶的 order_num 顯示 NULL。
SELECT customers.cust_id, cust_name, orders.order_num
FROM customers RIGHT OUTER JOIN orders
ON customers.cust_id = orders.cust_id;
SELECT customers.cust_id, cust_name, COUNT(orders.order_num) AS num_ord
FROM customers INNER JOIN orders
ON customers.cust_id = orders.cust_id
GROUP BY customers.cust_id;
統計每客戶訂單數。
虛擬表,不儲存數據,僅儲存 SELECT 查詢定義。使用時動態執行底層查詢。
代價:每次查詢視圖都執行底層 SQL,大數據量需注意效能。
-- 創建
CREATE VIEW view_name AS SELECT ...;
-- 查看定義
SHOW CREATE VIEW view_name;
-- 刪除
DROP VIEW view_name;
-- 更新(不存在則創建,存在則替換)
CREATE OR REPLACE VIEW view_name AS SELECT ...;
CREATE VIEW productcustomers AS
SELECT cust_name, cust_contact, prod_id
FROM customers, orders, orderitems
WHERE customers.cust_id = orders.cust_id
AND orders.order_num = orderitems.order_num;
-- 使用視圖
SELECT cust_name, cust_contact FROM productcustomers WHERE prod_id = 'TNT2';
CREATE VIEW vendorlocations AS
SELECT CONCAT(RTRIM(vend_name), ' (', RTRIM(vend_country), ')') AS vend_title
FROM vendors ORDER BY vend_name;
SELECT * FROM vendorlocations;
CREATE VIEW customeremaillist AS
SELECT cust_id, cust_name, cust_email
FROM customers
WHERE cust_email IS NOT NULL;
SELECT * FROM customeremaillist;
CREATE VIEW orderitemsexpanded AS
SELECT order_num, prod_id, quantity, item_price,
quantity * item_price AS expanded_price
FROM orderitems;
SELECT * FROM orderitemsexpanded WHERE order_num = 20005;
DESC orderitemsexpanded;
SHOW CREATE VIEW orderitemsexpanded;
-- 查詢所有視圖
USE information_schema;
SELECT TABLE_NAME, DEFINER FROM VIEWS;
掌握聯結與視圖,是從寫單表 SQL 進階到處理真實業務數據模型的關鍵一步。