1. 程式人生 > >python學習筆記 day44 mysql練習題(三)

python學習筆記 day44 mysql練習題(三)

題目來自於:http://www.cnblogs.com/wangfengming/articles/7978183.html

 

首先建立表 :

-- 建立資料表
  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 -- 是否打折 ); -- 寫入記錄 INSERT 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('玄龍精英版 筆記本散熱器','筆記本配件','九州風神','23455',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); select * from tdb_goods;
View Code

 

建立好的表如下:


2.  求所有電腦產品的平均價格,並且保留兩位小數,AVG,MAX,MIN,COUNT,SUM為聚合函式

select format(avg(goods_price),2) from tdb_goods;  -- avg(goods_price的是很多位小數,可以使用format(avg(goods_price),2))將查詢結果格式化輸出

 

執行結果:


3.查詢所有價格大於平均價格的商品,並且按價格降序排序

select * from tdb_goods where goods_price>(select avg(goods_price) from tdb_goods ) order by goods_price desc;

執行結果:

 

 4.查詢型別為“超記本”的商品價格

 

select goods_name,goods_price from tdb_goods where goods_cate="超級本";

 執行結果:

 

5.查詢價格等於"超級本"價格的商品,並且按價格降序排列

 

select goods_name,goods_price,goods_cate,brand_name from tdb_goods where goods_price in
 (select goods_price from tdb_goods where goods_cate="超級本")
order by goods_price desc;

 

執行結果:


6.建立“商品類別”表

create table if not exists tdb_goods_cate(
  cate_id smallint unsigned primary key auto_increment,
  cate_name varchar(40))
desc tdb_goods_cate;

執行結果:

 

 7.查詢tdb_goods表的類別記錄,並且按"類別"分組

 

select goods_cate from tdb_goods group by goods_cate;

執行結果:

 

 8.將分組結果寫入到tdb_goods_cates資料表(!!!)

就是把一個表的一列結果插入到另一個表格的一列;使用insert 需要增加列的表格名稱(要插入的列) select 需要把這一列給別的表 from 另一個表格的名稱

 

insert tdb_goods_cate(cate_name) select goods_cate from tdb_goods group by goods_cate;   -- 把一個表格的一列資料插入到另一個表格的一列!!
select * from tdb_goods_cate;

執行結果:

 

 9.通過tdb_goods_cates資料表來更新tdb_goods表中的'類別欄位'(!!!)

 剛才沒看懂題目意思:其實就是把tdb_goods表中的goods_cate 變為tdb_goods_cate表中名字相同的cate_id 類別號!!

思路就是首先通過內連線(關聯欄位是tdb_goods的goods_cate和tdb_goods_cate表的cate_name)建立臨時表,更新tdb_goods表的goods_cate;

select * from tdb_goods inner join tdb_goods_cate on tdb_goods.goods_cate = tdb_goods_cate.cate_name;  -- 兩張表通過goods_cate 與cate_name建立內連線;

update tdb_goods inner join tdb_goods_cate on tdb_goods.goods_cate=tdb_goods_cate.cate_name set goods_cate=cate_id;   -- 通過內連線建立的臨時表,更新goods_cate欄位為同行的cate_id;

select * from tdb_goods;   -- 檢視更新過之後的tdb_goods表;

執行結果:

 

 10.通過CREATE...SELECT來 建立[品牌]表 並且同時寫入記錄

 其實有兩種方法:

方法一: 首先建立一個品牌表tdb_goods_brand(brand_id ,brand_name) 然後把tdb_goods的brand_name插入到新建立的品牌表:

就是 insert tdb_goods_brand(brand_name) select brand_name from tdb_goods group by brand_name; -----流程跟之前取tdb_goods的goods_cate列插入到tdb_goods_cate是一樣的

create table if not exists tdb_goods_brand_1(          -- 建立一張新的表tdb_goods_brand
  brand_id smallint unsigned auto_increment primary key,
  brand_name varchar(40))       

select brand_name from tdb_goods group by brand_name;  -- 查詢tdb_goods表中的brand_name欄位資訊(按照brand_name分組)
insert tdb_goods_brand_1(brand_name) select brand_name from tdb_goods group by brand_name;

select * from tdb_goods_brand_1;

 

執行結果:

方法二:create table select 的時候就插入欄位值:

select * from tdb_goods_brand_1;

select brand_name from tdb_goods group by brand_name;   -- 按照brand_name分組查詢tdb_goods表中的品牌資訊,需要把brand_name資訊插入到tdb_goods_brand表中;

create table if not exists tdb_goods_brand(
  brand_id smallint unsigned auto_increment primary key,
  brand_name varchar(40)) select brand_name from tdb_goods group by brand_name;

select * from tdb_goods_brand;

 

執行結果:

 

11.通過tdb_goods_brands 品牌表 來更新 tdb_goods商品表

 思路跟上面通過tdb_goods_cate表的cate_name與tdb_goods表的goods_cate建立關聯,然後把tdb_goods的欄位goods_cate 替換成對應的tdb_goods_cate表的cate_id欄位;

所以操作如下:

select * from tdb_goods inner join tdb_goods_brand on tdb_goods.brand_name=tdb_goods_brand.brand_name;  -- 使用內連線通過兩張表的brand_name建立連線

update tdb_goods inner join tdb_goods_brand on tdb_goods.brand_name=tdb_goods_brand.brand_name 
set tdb_goods.brand_name=tdb_goods_brand.brand_id  -- 對通過brand_name建立的內連線的臨時表 更新tdb_goods的brand_name欄位,更新為tdb_goods_brand的brand_id欄位值;

select * from tdb_goods;

 

 執行結果:

 

 

 12.檢視tdb_goods的資料表結構

desc tdb_goods;  -- 檢視tdb_goods表的結構;

執行結果:

13.通過ALTER TABLE語句修改商品表結構,goods_cate更新為cate_id, brand_name更新為brand_id

 

alter table tdb_goods change goods_cate cate_id smallint unsigned;  -- 其實tdb_goods表中的goods_cate 與brand_name 都是另外兩張表tdb_goods_cate tdb_gods_brand的主鍵
alter table tdb_goods change brand_name brand_id smallint unsigned;  -- 更新表字段名稱使用change(modify只可以更新表字段的屬性,不可以改欄位名字)
desc tdb_goods;

執行結果:

(更改的這兩個欄位分別是兩外兩張表的主鍵,與他們建立聯絡的關聯欄位,其實可以設為外來鍵,便於查詢);

14.分別在tdb_goods_cates(類別表)和tdb_goods_brands(品牌表)插入記錄

 

insert into tdb_goods_cate(cate_name) values("路由器"),("交換機"),("網絡卡");
insert into tdb_goods_brand(brand_name) values("海爾"),("清華同方"),("神州");

 

 15.在tdb_goods資料表寫入任意記錄

 

INSERT into tdb_goods(goods_name,cate_id,brand_id,goods_price) VALUES('LaserJet Pro P1606dn 黑白鐳射印表機','12','4','1849');

16.查詢所有商品的詳細資訊(通過內連線實現)

 

select goods_id,goods_name,cate_id,tdb_goods_join_cate.brand_id,goods_price,is_show,is_saleoff,cate_name,brand_name  from
(select goods_id,goods_name,tdb_goods.cate_id,tdb_goods.brand_id,goods_price,is_show,is_saleoff,cate_name from tdb_goods 
inner join tdb_goods_cate 
on tdb_goods.cate_id=tdb_goods_cate.cate_id)as tdb_goods_join_cate
inner join 
tdb_goods_brand 
on tdb_goods_join_cate.brand_id = tdb_goods_brand.brand_id;

 

執行結果:

 

 啊 我寫的太麻煩了(先連線兩個,然後使用前兩個連線的結果跟第三個表再進行內連線,,,,)

其實簡便方法如下:

select goods_id,goods_name,g.cate_id,cate_name,g.brand_id,brand_name from tdb_goods as g
inner join tdb_goods_cate as c on g.cate_id=c.cate_id
inner join tdb_goods_brand as b on g.brand_id=b.brand_id;

 

執行結果:

17.查詢所有商品的詳細資訊(通過左外連線實現)

 

select goods_id,goods_name,g.cate_id,g.brand_id,cate_name,brand_name,goods_price,is_show,is_saleoff from tdb_goods as g
left join tdb_goods_cate as c on g.cate_id = c.cate_id 
left join tdb_goods_brand as b on g.brand_id=b.brand_id;

執行結果:

 

 18.查詢所有商品的詳細資訊(通過右外連線實現)

 

select goods_id,goods_name,g.cate_id,g.brand_id,goods_price,is_show,is_saleoff,cate_name,brand_name from tdb_goods as g
right join tdb_goods_cate as c on g.cate_id=c.cate_id
right join tdb_goods_brand as b on g.brand_id=b.brand_id;

19.無限分類的資料表設計

 

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
);
 
INSERT tdb_goods_types(type_name,parent_id) VALUES('家用電器',DEFAULT);
INSERT tdb_goods_types(type_name,parent_id) VALUES('電腦、辦公',DEFAULT);
INSERT tdb_goods_types(type_name,parent_id) VALUES('大家電',1);
INSERT tdb_goods_types(type_name,parent_id) VALUES('生活電器',1);
INSERT tdb_goods_types(type_name,parent_id) VALUES('平板電視',3);
INSERT tdb_goods_types(type_name,parent_id) VALUES('空調',3);
INSERT tdb_goods_types(type_name,parent_id) VALUES('電風扇',4);
INSERT tdb_goods_types(type_name,parent_id) VALUES('飲水機',4);
INSERT tdb_goods_types(type_name,parent_id) VALUES('電腦整機',2);
INSERT tdb_goods_types(type_name,parent_id) VALUES('電腦配件',2);
INSERT tdb_goods_types(type_name,parent_id) VALUES('筆記本',9);
INSERT tdb_goods_types(type_name,parent_id) VALUES('超級本',9);
INSERT tdb_goods_types(type_name,parent_id) VALUES('遊戲本',9);
INSERT tdb_goods_types(type_name,parent_id) VALUES('CPU',10);
INSERT tdb_goods_types(type_name,parent_id) VALUES('主機',10);


select * from tdb_goods_types;

執行結果:

 

 20.查詢所有分類及其父類(將自身作為臨時表使用)

 

select type_id,type_name,parent_id,(select type_name from tdb_goods_types where type_id=t1.parent_id)as parent_name from tdb_goods_types as t1;
-- 括號裡面的查詢語句是查詢parent_id對應的type_name 將查詢結果作為一個欄位parent_name

執行結果:

21. 複製tdb_goods表中編號為12,20的兩條記錄,新增到tdb_goods表格中:

select * from tdb_goods where goods_id in (12,20);  -- 先查詢到tdb_goods表中goods_id 為12 20 的這兩條資料

insert into tdb_goods(goods_name,cate_id,brand_id,goods_price,is_show,is_saleoff) select goods_name,cate_id,brand_id,goods_price,is_show,is_saleoff 
from tdb_goods where goods_id in (12,20);  -- 往tdb_goods表格中插入兩條重複的資料;

select * from tdb_goods;

 

執行結果:

 

 

 22.查詢重複記錄(!!!)竟然沒想到!!

select * from tdb_goods;

select GROUP_CONCAT(goods_id) from tdb_goods group by goods_name having count(goods_name)>=2; -- 可以顯示重複的一組都有哪些goods_id(按照goods_name分組)

select goods_id,goods_name,goods_price from tdb_goods group by goods_name having count(goods_name)>=2;

 

執行結果:

 


 

 23. 刪除重複記錄 

 

select max(goods_id) from tdb_goods group by goods_name having count(goods_name)>=2;   -- 把重複的goods_id(選一組裡重複的goods_id大的那個選出來刪掉)篩選選出來

select goods_id from tdb_goods group by goods_name having count(goods_name)>=2; -- 篩選重複的goods_id

delete from tdb_goods_copy where goods_id in (select max(goods_id) from tdb_goods group by goods_name having count(goods_name)>=2);
select * from tdb_goods_copy;

執行結果: