5-1 數據準備
創建數據庫
CREATE TABLE IF NOT EXISTS tdb_goods(
goods_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
goods_name VARCHAR(150) NOT NULL,
goods_cate VARCHAR(40) NOT NULL,
brand_name VARCHAR(40) NOT NULL,
goods_price DECIMAL(15,3) UNSIGNED NOT NULL DEFAULT 0,
is_show BOOLEAN NOT NULL DEFAULT 1,
is_saleoff BOOLEAN NOT NULL DEFAULT 0
);
如果中文顯示爲亂碼,或者無法插入中文,則設置客戶端的編碼方式,與數據無關
SET NAMES gbk;
寫入記錄
NSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('R510VC 15.6英寸筆記本','筆記本','華碩','3399',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('Y400N 14.0英寸筆記本電腦','筆記本','聯想','4899',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('G150TH 15.6英寸遊戲本','遊戲本','雷神','8499',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('X550CC 15.6英寸筆記本','筆記本','華碩','2799',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('X240(20ALA0EYCD) 12.5英寸超極本','超級本','聯想','4999',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('U330P 13.3英寸超極本','超級本','聯想','4299',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('SVP13226SCB 13.3英寸觸控超極本','超級本','索尼','7999',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('iPad mini MD531CH/A 7.9英寸平板電腦','平板電腦','蘋果','1998',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('iPad Air MD788CH/A 9.7英寸平板電腦 (16G WiFi版)','平板電腦','蘋果','3388',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES(' iPad mini ME279CH/A 配備 Retina 顯示屏 7.9英寸平板電腦 (16G WiFi版)','平板電腦','蘋果','2788',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('IdeaCentre C340 20英寸一體電腦 ','臺式機','聯想','3499',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('Vostro 3800-R1206 臺式電腦','臺式機','戴爾','2899',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('iMac ME086CH/A 21.5英寸一體電腦','臺式機','蘋果','9188',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('AT7-7414LP 臺式電腦 (i5-3450四核 4G 500G 2G獨顯 DVD 鍵鼠 Linux )','臺式機','宏碁','3699',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('Z220SFF F4F06PA工作站','服務器/工作站','惠普','4288',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('PowerEdge T110 II服務器','服務器/工作站','戴爾','5388',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('Mac Pro MD878CH/A 專業級臺式電腦','服務器/工作站','蘋果','28888',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES(' HMZ-T3W 頭戴顯示設備','筆記本配件','索尼','6999',DEFAULT,DEFAULT);INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('商務雙肩揹包','筆記本配件','索尼','99',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('X3250 M4機架式服務器 2583i14','服務器/工作站','IBM','6888',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('玄龍精英版 筆記本散熱器','筆記本配件','九州風神','',DEFAULT,DEFAULT);INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES(' HMZ-T3W 頭戴顯示設備','筆記本配件','索尼','6999',DEFAULT,DEFAULT);
INSERT tdb_goods (goods_name,goods_cate,brand_name,goods_price,is_show,is_saleoff) VALUES('商務雙肩揹包','筆記本配件','索尼','99',DEFAULT,DEFAULT);
5-2 子查詢簡介
子查詢是指出現在【其他SQL語句內】的SELECT子句
eg:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
其中,SELECT * FROM t1 ...稱爲Outer Query[外查詢](或者Outer Statement)
SELECT column1 FROM t2 稱爲Sub Query[子查詢]
- 子查詢指嵌套在【查詢內部】,且必須始終出現在【圓括號內】。
- 子查詢可以包含多個關鍵字或者條件,如DISTINCT,GROUP BY,ORDER BY,LIMIT,函數等
- 子查詢的外層查詢可以是:【SELECT,INSERT,UPDATE,SET或DO】
- 子查詢可以返回值:標量、一行、一列或者子查詢
5-3由比較運算符引發的子查詢
單獨分析篩選時
SELECT AVG(goods_price) FROM tdb_goods; //AVG函數代表求其平均值//
SELECT ROUND(AVG(goods_price),2) FROM tdb_goods; //round(@,#)代表輸出格式爲@數小數點後#位輸出//
SELECT goods_id,goods_name,goods_price FROM tdb_goods WHERE goods_price>=5391.30; //輸出價格大於5391.30的id、name、price//
綜合起來運用子查詢時
ELECT goods_id,goods_name,goods_price FROM tdb_goods WHERE goods_price>=(SELECT ROUND(AVG(goods_price),2) FROM tdb_goods); //查找價格大於平均值的商品//
SELECT goods_price FROM tdb_price WHERE goods_cate='超級本'\G; //檢索結果非唯一//
對於ANY、SOME、ALL的用法各有不同
SELECT goods_id,goods_name,goods_price FROM tdb_goods WHERE goods_price>=ANY (SELECT goods_price FROM tdb_goods WHERE goods_cate='超級本');
SELECT goods_id,goods_name,goods_price FROM tdb_goods WHERE goods_price>=ALL (SELECT goods_price FROM tdb_goods WHERE goods_cate='超級本');
SELECT goods_id,goods_name,goods_price FROM tdb_goods WHERE goods_price>=SOME (SELECT goods_price FROM tdb_goods WHERE goods_cate='超級本');
5-4 由[NOT] IN/EXISTS引發的子查詢
子查詢---in not in
- in 相當於=any
- not in 相當於 !=all 或者<>all ——不等於、不包含
子查詢----exists not exists ——用得比較少
- 如果子查詢返回任何行 exists返回true 否則返回 false
= ANY 或 = SOME 等價於 IN
SELECT goods_id,goods_name,goods_price FROM tdb_goods WHERE goods_price IN (SELECT goods_price FROM tdb_goods WHERE goods_cate = '超級本')
5-5使用INSERT...SELECT插入記錄
INSERT [INTO] tbl_name SET col_name={exprDEFAULT},...//可以使用子查詢
INSERT [INTO] tbl_name [(col_name,...)] SELECT ...//將查詢結果寫入數據表
Eg:
INSERT INTO table_name [(column_name)] SELECT column_name2 FROM table_name2 GROUP BY column_name3;
創建商品分類表
CREATE TABLE IF NOT EXISTS tdb_goods_cates(
cate_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
cate_name VARCHAR(40) NOT NULL
);
SELECT goods_cate FROM tdb_goods GROUP BY goods_cate; //列出所有品牌cate
DESC tdb_goods_cates; //顯示出tdb_goods_cates表中的項目名稱,與SHOW COLUMNS FROM tdb_goods_cates;作用相同
INSERT tdb_goods_cates(cate_name) SELECT goods_cate FROM tdb_goods GROUP BY goods_cate;//在表tdb_goods_cates中插入tdb_goods中的cate
5-6多表更新
UPDATE table_references SET col_name1={expr1 | DEFAULT} [,col_name2={expr2 | DEFAULT}]... [WHERE where_condition]
- INNER JOIN,內連接
- 在MySQL中,JOIN, CROSS JOIN 和 INNER JOIN 是等價的。
- LEFT [OUTER] JOIN ,左外連接
- RIGHT [OUTER] JOIN,右外連接
update tdb_goods inner join tdb_goods_cates on goods_cate=cate_name set goods_cate=cate_id;
- tdb_goods:想要更改的表名
- inner join: 內連接
- tdb_goods_cates: 關聯的附表
- goods_cate=cate_name 兩個表對應列的關係
- goods_cate=cate_id; 設置 值
5-7 多表更新之一步到位
建表、查詢、寫入三合一
CREATE TABLE tdb_goods_brands (
brand_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
brand_name VARCHAR(40) NOT NULL
)
SELECT brand_name FROM tdb_goods GROUP BY brand_name;
多表更新
UPDATE tdb_goods AS g INNER JOIN tdb_goods_brands AS b ON g.brand_name = b.brand_name SET g.brand_name = b.brand_id;
通過ALTER TABLE語句修改數據表結構
ALTER TABLE tdb_goods
CHANGE goods_cate cate_id SMALLINT UNSIGNED NOT NULL,
CHANGE brand_name brand_id SMALLINT UNSIGNED NOT NULL;
- PS:外鍵,不一定是物理的外鍵,邏輯的外鍵也行,當然,物理外鍵更能保證數據的完整性和一致性。 數字類型的字段佔用的空間更小,查詢的效率也更高。
5-8 連接的語法結構
MySQL在SELECT語句、多表更新、多表刪除語句中支持JOIN操作。
table reference A
{[INNER|CROSS] JOIN | {LEFT|RIGHT} [OUTER] JOIN}
table_reference B
ON condition_expr
數據表參照
table_reference
tbl_name [[AS] alias] | table_subquery [AS] alias
數據表可以使用tbl_name AS alias_name 或 tbl_name alias_name賦予別名。
table_subquery可以作爲子查詢使用在FROM子句中,這樣的子查詢必須爲其賦予別名。
5-9 內連接INNER JOIN
- 在MySQL中JOIN,INNER JOIN,CROSS JOIN是等價的
- 交集 僅顯示A、B兩表符合連接條件的記錄。不符合連接條件的記錄不顯示。
5-10外鏈接 OUTER JOIN
- LEFT JOIN:顯示左表全部和左右符合連接條件的記錄
- RIGHT JOIN:顯示左右符合連接條件的記錄和右表全部記錄
- 若某字段只存在某一表,則另一表的裏字段返回null
5-11多表連接
- 多表的連接跟兩張表的連接一樣
SELECT A.a,B.b,C.c
FROM tabA
JOIN tabB ON conditonal_expr
JOIN tabC ON conditonal_expr
5-12關於連接的幾點說明
外連接:
以左外連接爲例:
A LEFT JOIN B join_condition
- 數據表B的結果集依賴於數據表A
- 數據表A的結果集根據左連接條件依賴所有數據表(B表除外)
- 左外連接條件決定如何檢索數據表B(在沒有指定WHERE條件的情況下)
- 如果數據表A的某條記錄符合WHERE條件,但是在數據表B不存在符合連接條件的記錄,將生成一個所有列爲空的額外的B行
內連接:
- 使用內連接查找的記錄在連接數據表中不存在,並且在WHERE子句中嘗試以下操作:
- column_name IS NULL 。如果 column_name 被指定爲 NOT NULL,MySQL將在找到符合連接着條件的記錄後停止搜索更多的行(查找衝突)
5-13無限級分類表設計
CREATE TABLE tdb_goods_types(
type_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
type_name VARCHAR(20) NOT NULL,
parent_id SMALLINT UNSIGNED NOT NULL DEFAULT 0
);
無限分類
- 即在同一張表中既有父類,又有子類
- 通過在分類表中再增加多一個字段標識其屬於哪一個父類的 ID 來實現
- 可以通過對同一張數據表的自身連接來進行查詢,需要對錶標識別名
查找顯示父級id對應的名稱
select s.type_id ,s.type_name,p.type_name As parent_id from tdb_goods_types s left join
tdb_goods_types p on s.parent_id=p.type_id;
查找子級對應的名稱
select p.type_id ,p.type_name,s.type_name from tdb_goods_types p left join
tdb_goods_types s on p.type_id=s.parent_id;
查找有多少子級
select p.type_id ,p.type_name,COUNT(s.type_name) from tdb_goods_types p left join
tdb_goods_types s on p.type_id=s.parent_id
GROUP BY p.type_name ORDER BY p.type_id;
5-14多表刪除
delete t1 from tdb_goods as t1 //從本表中刪除,將tdb_goods看做t1
left join (select goods_id,goods_name from tdb_goods group by goods_name having count(goods_name)>=2) as t2 //子查詢得到重複條目
on t1.goods_name=t2.goods_name //t1和t2的連接條件
where t1.goods_id>t2.goods_id; //刪除id號較大的條目