mysql複習php
二 基礎知識:css
1.數據庫的鏈接vue
mysql -u -p -hjava
-u 用戶名mysql
-p 密碼ios
-h host主機c++
2:庫級知識git
2.1 顯示數據庫: show databases;web
2.2 選擇數據庫: use dbname;面試
2.3 建立數據庫: create database dbname charset utf8;
2.3 刪除數據庫: drop database dbname;
3: 表級操做:
3.1 顯示庫下面的表
show tables;
會把視圖頁查出來
3.11 查看錶結構
Desc 表名/視圖名
3.2 查看錶的結構:
desc tableName;
3.3 查看錶的建立過程:
show create table tableName;
3.32 改表名
Rename table t1 to t2
3.33 刪除表
Drop table t1
Drop view v1 刪除視圖
3.4 建立表:
create table tbName (
列名稱1 列類型 [列參數] [not null default ],
....列2...
....
列名稱N 列類型 [列參數] [not null default ]
)engine myisam/innodb charset utf8/gbk
3.4的例子:
create table user (
id int auto_increment,
name varchar(20) not null default '',
age tinyint unsigned not null default 0,
index id (id)
)engine=innodb charset=utf8;
注:innodb是表引擎,也能夠是myisam或其餘,但最經常使用的是myisam和innodb,
charset 經常使用的有utf8,gbk;
爲何建表時,加not null default '' / default 0
答:不想讓表中出現null值.
爲何不想要的null的值
答:
很差比較,null是一種類型,比較時,只能用專門的is null 和 is not null來比較.
碰到運算符,一概返回null
效率不高,影響提升索引效果.
一張表,建立完畢,有了N列.
以後還有可能要增長或刪除或修改列
Alter table 表名 add 列名稱 列類型 列參數; [加的列在表的最後]
例: alter table m1 add birth date not null default '0000-00-00';
Alter table 表名 add 列名稱 列類型 列參數 after 某列 [把新列加在某列後]
例: alter table m1 add gender char(1) not null default '' after username;
Alter table 表名 add 列名稱 列類型 列參數 first [把新列加在最前面]
例: alter table m1 add pid int not null default 0 first;
刪除列:
Alter table 表名 drop 列名
修改列類型:
Alter table 表名 modify 列名 新類型 新參數
例:alter table m1 modify gender char(4) not null default '';
修改列名及列類型
Alter table 表名 change 舊列名 新列名 新類型 新參數
例:alter table m1 change id uid int unsigned;
做業: 讓咱們建一個電子商城, 如何來設計商品表.
再把商城表的字段,一個個刪掉,再一個個加上.
並穿插改列操做.
??若是列類型改變了,致使數據存不下怎麼辦?
好比,int 改爲smallint列. 若是不匹配,數據將會丟失,或者在mysql的strict_mode下,修改不了.
4.1
主鍵 primary key
此列不重複,能區分每一行
注意:一張表 只能1 列爲auto_increment 且此列必須加索引
在查詢中,咱們常常把查詢結果 當成臨時表來看.
View是什麼? View能夠看一張虛擬表. 是表經過某種運算獲得的一個投影.
既然視圖只是表的某種查詢的投影,因此主要步驟在於查詢表上.
查詢的結果命名爲視圖就能夠了.
視圖的定義:
視圖是由查詢結果造成的一張虛擬表.viem是sql的查詢結果
視圖的建立語法:
Create view 視圖名 as select 語句;
視圖的刪除語法:
Drop view 視圖名
爲何要視圖?
答:
1:能夠簡化查詢
2: 能夠進行權限控制
把表的權限封閉,可是開放相應的視圖權限,視圖裏只開放部分數據
3: 大數據分表時能夠用到
好比,表的行數超過200萬行時,就會變慢,
能夠把一張的表的數據拆成4張表來存放.
News表
Newsid, 1,2,3,4
News1,news2,news3,news4表
把一張表的數據分散到4張表裏,分散的方法不少,
最經常使用能夠用id取模來計算.
Id%4+1 = [1,2,3,4]
好比 $_GET['id'] = 17,
17%4 + 1 = 2, $tableName = 'news'.'2'
Select * from news2 where id = 17;
還能夠用視圖, 把4張表造成一張視圖
Create view news as select from n1 union select from n2 union.........
視圖的修改
Alter view 視圖名 as select xxxxxx
視圖是表的一個影子.
表與視圖,數據變化時的相互影響問題.
視圖與表的關係
視圖是表的查詢結果,天然表的數據改變了,影響視圖的結果.
視圖改變了呢?
0: 視圖增刪改也會影響表
1: 可是,視圖並是老是能增刪改的.
視圖某種狀況下,是能夠修改的.
要求: 視圖的數據和表的數據 11對應. 就像函數的映射.
表-->推出視圖對應的數據
視圖-->推出表對應的數據
對於視圖insert還應注意,
視圖必須包含表中沒有默認值的列.
以這個例子而言,平均價來自於多行的的shop_price的計算結果.
若是pj列的值的變子,映射過去,到底修改哪幾行shop_price?
視圖的algorithm
Algorithm = merge/ temptable/ undefined
Merge: 當引用視圖時,引用視圖的語句與定義視圖的語句合併.
Temptable:當引用視圖時,根據視圖的建立語句創建一個臨時表
Undefined:未定義,自動,讓系統幫你選.
Merge,意味着視圖只是一個規則,語句規則, 當查詢視圖時,
把查詢視圖的語句(好比where那些)與建立時的語句where子句等合併,分析.
造成一條select 語句.
例: 建立視圖的語句:
mysql> create view g2 as select goods_id,cat_id,goods_name,shop_price from goods where shop_price>2000
查詢視圖的語句:
select * from g2 where shop_price < 3000;
最終執行的語句:
select goods_id,cat_id,goods_name,shop_price from goods where shop_price > 2000 and shop_price < 3000
而temptable是根據建立語句瞬間建立一張臨時表,
而後查詢視圖的語句從該臨時表查數據.
create algorethm=temptable view g2 as select goods_id,cat_id,goods_name,shop_price from goods where shop_price > 2000
查詢視圖的語句:
select * from g2 where shop_price < 3000;
最終執行的2句話: 取數據並放在臨時表,而後去查臨時表.
Select goods_id,cat_id,goods_name,shop_price from goods where shop_price > 2000;
========> temptable
再次查臨時表
Select * from temptable where shop_price< 3000
列類型學習
mysql三大列類型
數值型
整型
Tinyint/ smallint/ mediumint/int/ bigint(M) unsigned zerofill
整型系列所佔字節與存儲範圍的關係.
定性: 佔字節越多,存儲範圍越大.
下圖: 是具體的數字分析
整型系統的可選參數 : XXint(M) unsigned zerofill
例: age tinyint(4) unsigned ,或者 stunum smallint(6) zerofill;
Unsigned: 表明此列爲無符號類型, 會影響到列的存儲範圍. (範圍從0開始)
(不加unsinged, 則該列默認是有符號類型,範圍從負數開始)
Zerofill: 表明0填充, 即: 若是該數字不足參數M位, 則自動補0, 補夠M位.
1: 若是沒有zerofill屬性, 單獨的參數M,沒有任何意義.
2:若是設置某列爲zerofill,則該列已經默認爲 unsigned,無符號類型.
小數型
Float(M,D),decimal(M,D)
M叫"精度" ---->表明"總位數",而D是"標度",表明小數位.(小數右邊的位數)
浮點數佔多大的空間呢
答: float 能存10^38 ,10^-38
若是M<=24, 點4個字節,不然佔8字節
用來表示數據中的小數,除了float---浮點.
還有一種叫定點decimal,定點是把整數部分, 和小數部分,分開存儲的.
比float精確,他的長度是變化的.
空間上的區別:
Float(M,D), M<=24, 4個字節, 24 <M <=53, 8個字節
Decimal () ,變長字節.
區別: decimal比float精度更高, 適合存儲貨幣等要求精確的數字,
:
字符串型
Char(M)
Varchar(M)
Text 文本類型
日期時間類型
Date 日期
Time 時間
Datetime 時間時間類型
Year 年類型
Mysql 字符串類型
Char 定長類型
Char(M) , M 表明寬度, 0<=M<=255之間
例:Char(10) ,則能輸入10個字符. 但只寫一個也算10個字符的寬度
Varchar 變長類型
Varchar(M), M表明寬度, 0<=M<=65535(以ascii字符爲例,utf822000左右)
類型
類型 |
寬度 |
可存字符 |
實存字符(i<=M) |
實佔空間 |
利用率 |
Char |
M |
M |
i |
M |
i/M <= 100% |
Varchar |
M |
M |
i |
i字符+(1-2)字節 |
i/(i+1-2) < 100% |
0000000000
00\0\0\0\0\0 (char型,若是不夠M個字符,內部用空格補齊,取出時再把右側空格刪掉)
注:這意味着,若是右側自己有空格,將會丟失.
Varchar(10)
[2]張三
[3]二麻子
[4]司馬相如
Char(8)
00000000
'Hello '
'hello '
Char(M)如何佔據M個字符寬度?
答: 若是實際存儲內容不足M個,則後面加空格補齊.
取出來的時候, 再把後面的空格去掉.(因此,若是內容最後有空格,將會被清除).
速度上: 定長速度快些
注意: char(M),varchar(M)限制的是字符,不是字節.
即 char(2) charset utf8, 能存2個utf8字符. 好比'中國'char與varchar型的選擇原則:
1:空間利用效率, 四字成語表, char(4),
我的簡介,微博140字, varchar(140)
2:速度
用戶名: char
Char 與 varchar相關實驗
Text : 文本類型,能夠存比較大的文本段,搜索速度稍慢.
所以,若是不是特別大的內容,建議用char,varchar來代替.
Text 不用加默認值 (加了也沒用).
Blob,是二進制類型,用來存儲圖像,音頻等二進制信息.
意義: 2進制,0-255都有可能出現.
Blob在於防止由於字符集的問題,致使信息丟失.
好比:一張圖片中有0xFF字節, 這個在ascii字符集認爲非法,在入庫的時候,被過濾了.
日期時間類型
Year 年(1字節) 95/1995, [1901-2155],
在insert時,能夠簡寫年的後2位,可是不推薦這樣.
[00-69] +2000
[70-99] + 1900,
即: 填2位,表示 1970 - 2069
Date 日期 1998-12-31
範圍: 1000/01/01 ,9999/12/31
Time 時間 13:56:23
範圍: -838:59:59 -->838:59:59
datetime 時期時間 1998-12-31 13:56:23
範圍: 1000/01//01 00:00:00 ---> 9999:12:31 23:59:59
timestamp
時間戳:
是1970-01-01 00:00:00 到當前的秒數.
通常存註冊時間,商品發佈時間等,並非用datetime存儲,而是用時間戳.
由於datetime雖然直觀,但計算不便.
3.5 修改表
3.5.1 修改表之增長列:
alter table tbName
add 列名稱1 列類型 [列參數] [not null default ] #(add以後的舊列名以後的語法和建立表時的列聲明同樣)
3.5.2 修改表之修改列
alter table tbName
change 舊列名 新列名 列類型 [列參數] [not null default ]
(注:舊列名以後的語法和建立表時的列聲明同樣)
3.5.3 修改表之減小列:
alter table tbName
drop 列名稱;
3.5.4 修改表之增長主鍵
alter table tbName add primary key(主鍵所在列名);
例:alter table goods add primary key(id)
該例是把主鍵創建在id列上
3.5.5 修改表之刪除主鍵
alter table tbName drop primary key;
3.5.6 修改表之增長索引
alter table tbName add [unique|fulltext] index 索引名(列名);
3.5.7 修改表之刪除索引
alter table tbName drop index 索引名;
3.5.8 清空表的數據
truncate tableName;
4:列類型講解
列類型:
整型:tinyint (0~255/-128~127) smallint (0~65535/-32768~32767) mediumint int bigint (參考手冊11.2)
參數解釋:
unsigned 無符號(不能爲負) zerofill 0填充 M 填充後的寬度
舉例:tinyint unsigned;
tinyint(6) zerofill;
數值型
浮點型:float double
格式:float(M,D) unsigned\zerofill;
字符型
char(m) 定長
varchar(m)變長
text
列 實存字符i 實佔空間 利用率
char(M) 0<=i<=M M i/m<=100%
varchar(M) 0<=i<=M i+1,2 i/i+1/2<100%
year YYYY 範圍:1901~2155. 可輸入值2位和4位(如98,2012)
日期時間類型 date YYYY-MM-DD 如:2010-03-14
time HH:MM:SS 如:19:26:32
datetime YYYY-MM-DD HH:MM:SS 如:2010-03-14 19:26:32
timestamp YYYY-MM-DD HH:MM:SS 特性:不用賦值,該列會爲本身賦當前的具體時間
5:增刪改查基本操做
5.1 插入數據
insert into 表名(col1,col2,……) values(val1,val2……); -- 插入指定列
insert into 表名 values (,,,,); -- 插入全部列
insert into 表名 values -- 一次插入多行
(val1,val2……),
(val1,val2……),
(val1,val2……);
5.3修改數據
update tablename
set
col1=newval1,
col2=newval2,
...
...
colN=newvalN
where 條件;
5.4,刪除數據 delete from tablenaeme where 條件;
5.5, select 查詢
select count(*) from 表名, 查詢的就是絕對的行數,哪怕某一行全部字段全爲NULL,也計算在內.
而select couht(列名) from 表名,
查詢的是該列不爲null的全部行的行數.
語法:
SELECT selection_list /*要查詢的列名稱*/
FROM table_list /*要查詢的表名稱*/
WHERE condition /*行條件*/
GROUP BY grouping_columns /*對結果分組*/
HAVING condition /*分組後的行條件*/
ORDER BY sorting_columns /*對結果分組*/
LIMIT offset_start, row_count /*結果限定*/
(1) 條件查詢 where a. 條件表達式的意義,表達式爲真,則該行取出
b. 比較運算符 = ,!=,< > <= >=
c. like , not like ('%'匹配任意多個字符,'_'匹配任意單個字符)
‘諾基亞_’ 諾基亞加一個字符
‘諾基亞%’ 諾基亞加任意多個字符
in , not in , between and
d. is null , is not null 表示是否是null, 不能用where ...=null
(2) 分組 group by
通常要配合5個聚合函數使用:max,min,sum,avg,count
Select avg(shop_price) from user group by cat_id 分組 每一個cat_id的平均
..... 同理
(3) 篩選 having
Select goods_id, (market_price-shop_price) as sheng from goods
Where 1
Having sheng >200; 篩選出差價大於200的
不能簡單地寫成where sheng>200
注意,WHERE是對分組前記錄的條件,若是某行記錄沒有知足WHERE子句的條件,那麼這行記錄不會參加分組;而HAVING是對分組後數據的約束。
(4) 排序 order by
Select goods_id from ecs_goods order by shop_price desc; 降序排列
Asc 或者不寫 ,就是升序
Select goods_id from ecs_goods order by cat_id asc, shop_price desc; 先按cat_id排,裏面按照shop_price排
(5) 限制 limit 跳過前面n條取x條
Select goods_name from goods order by shop_price desc limit 0,3偏移0行取三行
注:偏移量爲0能夠不寫,但不推薦
6: 鏈接查詢
6.1, 左鏈接
.. left join .. on
table A left join table B on tableA.col1 = tableB.col2 ;
例句:
select 列名 from table A left join table B on tableA.col1 = tableB.col2
2. 右連接: right join
3. 內鏈接: inner join
左右鏈接都是以在左邊的表的數據爲準,沿着左表查右表.
內鏈接是以兩張表都有的共同部分數據爲準,也就是左右鏈接的數據之交集.
左右與內不一樣的是,內遇到是null的就不取了,而左右仍是要取
左鏈接的語法:
假設A表在左,不動,B表在A表的右邊滑動.
A表與B表經過一個關係來篩選B表的行.
語法:
A left join B on 條件 條件爲真,則B表對應的行,取出
A left join B on 條件
這一塊,造成的也是一個結果集,能夠當作一張表 設爲C
既如此,能夠對C表做查詢,天然where,group ,having ,order by ,limit 照常使用
問:C表的能夠查詢的列有哪些列?
答: A B的列均可以查
主外鍵是構成表與表關聯的惟一途徑!
外鍵是另外一張表的主鍵!例如員工表與部門表之間就存在關聯關係,其中員工表中的部門編號字段就是外鍵,是相對部門表的外鍵。
咱們再來看BBS系統中:用戶表(t_user)、分類表(t_section)、帖子表(t_topic)三者之間的關係。
例如在t_section表中sid爲1的記錄說明有一個分類叫java,版主是t_user表中uid爲1的用戶,即zs!
例如在t_topic表中tid爲2的記錄是名字爲「Java是咖啡」的帖子,它是java版塊的帖子,它的做者是ww。
外鍵就是用來約束這一列的值必須是另外一張表的主鍵值!!!
l 建立t_user表,指定uid爲主鍵列:
CREATE TABLE t_user(
uid INT PRIMARY KEY AUTO_INCREMENT,
uname VARCHAR(20) UNIQUE NOT NULL
);
l 建立t_section表,指定sid爲主鍵列,u_id爲相對t_user表的uid列的外鍵:
CREATE TABLE t_section(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(30),
u_id INT,
CONSTRAINT fk_t_user FOREIGN KEY(u_id) REFERENCES t_user(uid)
);
l 修改t_section表,指定u_id爲相對t_user表的uid列的外鍵:
ALTER TABLE t_section
ADD CONSTRAINT fk_t_user
FOREIGN KEY(u_id)
REFERENCES t_user(uid);
l 修改t_section表,刪除u_id的外鍵約束:
ALTER TABLE t_section
DROP FOREIGN KEY fk_t_user;
l 一對一:例如t_person表和t_card表,即人和身份證。這種狀況須要找出主從關係,即誰是主表,誰是從表。人能夠沒有身份證,但身份證必需要有人才行,因此人是主表,而身份證是從表。設計從表能夠有兩種方案:
Ø 在t_card表中添加外鍵列(相對t_user表),而且給外鍵添加惟一約束;
Ø 給t_card表的主鍵添加外鍵約束(相對t_user表),即t_card表的主鍵也是外鍵。
l 一對多(多對一):最爲常見的就是一對多!一對多和多對一,這是從哪一個角度去看得出來的。t_user和t_section的關係,從t_user來看就是一對多,而從t_section的角度來看就是多對一!這種狀況都是在多方建立外鍵!
l 多對多:例如t_stu和t_teacher表,即一個學生能夠有多個老師,而一個老師也能夠有多個學生。這種狀況一般須要建立中間表來處理多對多關係。例如再建立一張表t_stu_tea表,給出兩個外鍵,一個相對t_stu表的外鍵,另外一個相對t_teacher表的外鍵。
多表查詢有以下幾種:
l 合併結果集;
l 鏈接查詢
Ø 內鏈接
Ø 外鏈接
² 左外鏈接
² 右外鏈接
² 全外鏈接(MySQL不支持)
Ø 天然鏈接
l 子查詢
1. 做用:合併結果集就是把兩個select語句的查詢結果合併到一塊兒!
2. 合併結果集有兩種方式:
l UNION:去除重複記錄,例如:SELECT * FROM t1 UNION SELECT * FROM t2;
l UNION ALL:不去除重複記錄,例如:SELECT * FROM t1 UNION ALL SELECT * FROM t2。
3. 要求:被合併的兩個結果:列數、列類型必須相同。
鏈接查詢就是求出多個表的乘積,例如t1鏈接t2,那麼查詢出的結果就是t1*t2。
鏈接查詢會產生笛卡爾積,假設集合A={a,b},集合B={0,1,2},則兩個集合的笛卡爾積爲{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。能夠擴展到多個集合的狀況。
那麼多表查詢產生這樣的結果並非咱們想要的,那麼怎麼去除重複的,不想要的記錄呢,固然是經過條件過濾。一般要查詢的多個表之間都存在關聯關係,那麼就經過關聯關係去除笛卡爾積。
你能想像到emp和dept錶鏈接查詢的結果麼?emp一共14行記錄,dept表一共4行記錄,那麼鏈接後查詢出的結果是56行記錄。
也就你只是想在查詢emp表的同時,把每一個員工的所在部門信息顯示出來,那麼就須要使用主外鍵來去除無用信息了。
使用主外鍵關係作爲條件來去除無用信息
SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno; |
上面查詢結果會把兩張表的全部列都查詢出來,也許你不須要那麼多列,這時就能夠指定要查詢的列了。
SELECT emp.ename,emp.sal,emp.comm,dept.dname FROM emp,dept WHERE emp.deptno=dept.deptno; |
還能夠爲表指定別名,而後在引用列時使用別名便可。
SELECT e.ename,e.sal,e.comm,d.dname FROM emp AS e,dept AS d WHERE e.deptno=d.deptno; |
2.1 內鏈接
上面的鏈接語句就是內鏈接,但它不是SQL標準中的查詢方式,能夠理解爲方言!SQL標準的內鏈接爲:
SELECT * FROM emp e INNER JOIN dept d ON e.deptno=d.deptno; |
內鏈接的特色:查詢結果必須知足條件。例如咱們向emp表中插入一條記錄:
其中deptno爲50,而在dept表中只有十、20、30、40部門,那麼上面的查詢結果中就不會出現「張三」這條記錄,由於它不能知足e.deptno=d.deptno這個條件。
2.2 外鏈接(左鏈接、右鏈接)
外鏈接的特色:查詢出的結果存在不知足條件的可能。
左鏈接:
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.deptno=d.deptno; |
左鏈接是先查詢出左表(即以左表爲主),而後查詢右表,右表中知足條件的顯示出來,不知足條件的顯示NULL。
這麼說你可能不太明白,咱們仍是用上面的例子來講明。其中emp表中「張三」這條記錄中,部門編號爲50,而dept表中不存在部門編號爲50的記錄,因此「張三」這條記錄,不能知足e.deptno=d.deptno這條件。但在左鏈接中,由於emp表是左表,因此左表中的記錄都會查詢出來,即「張三」這條記錄也會查出,但相應的右表部分顯示NULL。
2.3 右鏈接
右鏈接就是先把右表中全部記錄都查詢出來,而後左表知足條件的顯示,不知足顯示NULL。例如在dept表中的40部門並不存在員工,但在右鏈接中,若是dept表爲右表,那麼仍是會查出40部門,但相應的員工信息爲NULL。
SELECT * FROM emp e RIGHT OUTER JOIN dept d ON e.deptno=d.deptno; |
鏈接查詢心得:
鏈接不限與兩張表,鏈接查詢也能夠是三張、四張,甚至N張表的鏈接查詢。一般鏈接查詢不可能須要整個笛卡爾積,而只是須要其中一部分,那麼這時就須要使用條件來去除不須要的記錄。這個條件大多數狀況下都是使用主外鍵關係去除。
兩張表的鏈接查詢必定有一個主外鍵關係,三張表的鏈接查詢就必定有兩個主外鍵關係,因此在你們不是很熟悉鏈接查詢時,首先要學會去除無用笛卡爾積,那麼就是用主外鍵關係做爲條件來處理。若是兩張表的查詢,那麼至少有一個主外鍵條件,三張錶鏈接至少有兩個主外鍵條件。
你們也都知道,鏈接查詢會產生無用笛卡爾積,咱們一般使用主外鍵關係等式來去除它。而天然鏈接無需你去給出主外鍵等式,它會自動找到這一等式:
l 兩張鏈接的表中名稱和類型完成一致的列做爲條件,例如emp和dept表都存在deptno列,而且類型一致,因此會被天然鏈接找到!
固然天然鏈接還有其餘的查找條件的方式,但其餘方式均可能存在問題!
SELECT * FROM emp NATURAL JOIN dept; SELECT * FROM emp NATURAL LEFT JOIN dept; SELECT * FROM emp NATURAL RIGHT JOIN dept; |
子查詢就是嵌套查詢,即SELECT中包含SELECT,若是一條語句中存在兩個,或兩個以上SELECT,那麼就是子查詢語句了。
l 子查詢出現的位置:
Ø where後,做爲條件的一部分;
Ø from後,做爲被查詢的一條表;
l 當子查詢出如今where後做爲條件時,還可使用以下關鍵字:
Ø any
Ø all
l 子查詢結果集的形式:
Ø 單行單列(用於條件)
Ø 單行多列(用於條件)
Ø 多行單列(用於條件)
Ø 多行多列(用於表)
練習:
1. 工資高於甘寧的員工。
分析:
查詢條件:工資>甘寧工資,其中甘寧工資須要一條子查詢。
第一步:查詢甘寧的工資
SELECT sal FROM emp WHERE ename='甘寧' |
第二步:查詢高於甘寧工資的員工
SELECT * FROM emp WHERE sal > (${第一步}) |
結果:
SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename='甘寧') |
l 子查詢做爲條件
l 子查詢形式爲單行單列
2. 工資高於30部門全部人的員工信息
分析:
查詢條件:工資高於30部門全部人工資,其中30部門全部人工資是子查詢。高於全部須要使用all關鍵字。
第一步:查詢30部門全部人工資
SELECT sal FROM emp WHERE deptno=30; |
第二步:查詢高於30部門全部人工資的員工信息
SELECT * FROM emp WHERE sal > ALL (${第一步}) |
結果:
SELECT * FROM emp WHERE sal > ALL (SELECT sal FROM emp WHERE deptno=30) |
l 子查詢做爲條件
l 子查詢形式爲多行單列(當子查詢結果集形式爲多行單列時可使用ALL或ANY關鍵字)
3. 查詢工做和工資與殷天正徹底相同的員工信息
分析:
查詢條件:工做和工資與殷天正徹底相同,這是子查詢
第一步:查詢出殷天正的工做和工資
SELECT job,sal FROM emp WHERE ename='殷天正' |
第二步:查詢出與殷天正工做和工資相同的人
SELECT * FROM emp WHERE (job,sal) IN (${第一步}) |
結果:
SELECT * FROM emp WHERE (job,sal) IN (SELECT job,sal FROM emp WHERE ename='殷天正') |
l 子查詢做爲條件
l 子查詢形式爲單行多列
4. 查詢員工編號爲1006的員工名稱、員工工資、部門名稱、部門地址
分析:
查詢列:員工名稱、員工工資、部門名稱、部門地址
查詢表:emp和dept,分析得出,不須要外鏈接(外鏈接的特性:某一行(或某些行)記錄上會出現一半有值,一半爲NULL值)
條件:員工編號爲1006
第一步:去除多表,只查一張表,這裏去除部門表,只查員工表
SELECT ename, sal FROM emp e WHERE empno=1006 |
第二步:讓第一步與dept作內鏈接查詢,添加主外鍵條件去除無用笛卡爾積
SELECT e.ename, e.sal, d.dname, d.loc FROM emp e, dept d WHERE e.deptno=d.deptno AND empno=1006 |
第二步中的dept表表示全部行全部列的一張完整的表,這裏能夠把dept替換成全部行,但只有dname和loc列的表,這須要子查詢。
第三步:查詢dept表中dname和loc兩列,由於deptno會被做爲條件,用來去除無用笛卡爾積,因此須要查詢它。
SELECT dname,loc,deptno FROM dept; |
第四步:替換第二步中的dept
SELECT e.ename, e.sal, d.dname, d.loc FROM emp e, (SELECT dname,loc,deptno FROM dept) d WHERE e.deptno=d.deptno AND e.empno=1006 |
l 子查詢做爲表
l 子查詢形式爲多行多列
同窗見面會:
男生表
姓名 |
配偶 |
張三 |
A |
李四 |
B |
王五 |
C |
高富帥 |
D |
鄭七 |
E |
女生表
姓名 |
配偶 |
空姐 |
B |
大S |
C |
阿嬌 |
D |
張柏芝 |
D |
林黛玉 |
E |
寶釵 |
F |
主持人大聲說:
全部的男士,站到舞臺上,帶上本身的配偶,(沒有的拿塊牌子, 上寫NULL)
思考:張三上不上舞臺呢?
答:上,
問:張三沒有對應的行怎麼辦?
答:用NULL補齊
結果以下
姓名 |
配偶 |
女生姓名 |
配偶 |
張三 |
A |
NULL |
NULL |
李四 |
B |
空姐 |
B |
王五 |
C |
大S |
C |
高富帥 |
D |
阿嬌 |
D |
高富帥 |
D |
張柏芝 |
D |
鄭七 |
E |
林黛玉 |
E |
這種狀況就是 男生 left join 女生.
主持人說:全部女生請上舞臺,有配偶的帶着, 沒有的,寫個NULL補齊.
Select 女生 left join 男生 on 條件
左右鏈接是能夠互換的
A left join B, 就等價於 B right join A
注意:既然左右鏈接能夠互換,儘可能用左鏈接,出於移植時兼容性方面的考慮.
內鏈接的特色
主持人說: 全部有配偶的男生/女生,走到舞臺上來
這種狀況下: 張三和寶釵都出局
姓名 |
配偶 |
女生姓名 |
配偶 |
李四 |
B |
空姐 |
B |
王五 |
C |
大S |
C |
高富帥 |
D |
阿嬌 |
D |
高富帥 |
D |
張柏芝 |
D |
鄭七 |
E |
林黛玉 |
E |
若是從集合的角度
A inner join B
和 left join /right join的關係
答: 內鏈接是左右鏈接的交集
問題:
主持人說:全部男生/女生,走上舞臺.
有配偶的,帶着配偶;
沒配偶的,拿牌子寫NULL
即:結果是左右鏈接的並集
這種叫作外鏈接,可是,在mysql中不支持外鏈接
Union:合併2條或多條語句的結果
語法:
Sql1 union sql2
可否從2張表查詢再union呢?
答:能夠,union 合併的是"結果集",不區分在自於哪一張表.
問:取自於2張表,經過"別名"讓2個結果集的列一致.
那麼,若是取出的結果集,列名字不同,還可否union.
答:能夠,以下圖,並且取出的最終列名,以第1條sql爲準
問:union知足什麼條件就能夠用了?
答:只要結果集中的列數一致就能夠.
問:列的類型不同,也行嗎?
答:能夠,列名稱未必要一致 會使用第一條sql的列名稱
問: union後結果集,能否再排序呢?
答:能夠的.
Sql1 union sql2 order by 字段
注意: order by 是針對合併後的結果集排的序.
若是不是union all 就會把徹底相同的行合併在一塊兒
問: 使用order by 的注意事項
以下,內層語句的desc怎麼沒發揮做用呢?
思考以下語句:
(SELECT goods_id,cat_id,goods_name,shop_price FROM goods WHERE cat_id = 4 ORDER BY shop_price DESC)
UNION
(SELECT goods_id,cat_id,goods_name,shop_price FROM goods WHERE cat_id = 5 ORDER BY shop_price DESC)
order by shop_price asc;
Union的子句中,不用寫orderBy
Sql合併後獲得的總的結果,能夠orderby ,子句orderby就失去意義了
所以:內層的order by 語句單獨使用,不會影響結果集,僅排序,
在執行期間,就被Mysql的代碼分析器給優化掉了.
內層的order by 必須可以影響結果集時,纔有意義.
好比 配合limit 使用. 以下例.
思考下個問題:
查出: 第3個欄目下,價格前3高的商品,和第4個欄目下,價格前2高的商品.
用union來完成
這一次:內層的order by 發揮了做用,由於有limit ,order 會實際影響結果集,有意義.
若是Union後的結果有重複(即某2行,或N行,全部的列,值都同樣),怎麼辦?
答:這種狀況是比較常見的,默認會去重.
問:若是不想去重怎麼辦?
答: union all
7 子查詢
where 型子查詢:內層sql的返回值在where後做爲條件表達式的一部分
若是 where 列=(內層sql),則內層sql返回的必是單行單列,單個值
若是 where 列 in (內層sql), 則內層sql只返回單列,能夠多行.
例句: select * from tableA where colA = (select colB from tableB where ...);
每一個欄目下最想的商品
from 型子查詢:內層sql查詢結果,做爲一張表,供外層的sql語句再次查詢
例句:select * from (select * from ...) as tableName where ....
9. 存儲引擎
Show table status where name=’t11’
就能夠查看錶的信息 能夠看到引擎
存儲引擎 engine=1\2
1 Myisam 速度快 不支持事務 回滾
2 Innodb 速度慢 支持事務,回滾
字符集與亂碼問題
客服端sql編碼 character_set_client
服務器轉化後的sql編碼 character_set_connection
服務器返回給客戶端的結果集編碼 character_set_results
快速把以上3個變量設爲相同值: set names 字符集
➕頁面自己 ... 這幾步設完就不亂碼了
校對集
就是按照什麼排序而已
經常使用函數
Floor(向下取整)
Round 四捨五入
Rand() 0到1的隨機值
Ceiling 向上取整
Count 非null的個數
Cancat(s1,s2) ...連起來
Length 返回字符串str中的字符數
Trim 去掉頭尾空格
索引
是數據的目錄,能快速定位行數據的位置
提升查詢速度,可是下降了增刪改的速度,因此使用索引時,要綜合考慮.
通常在查詢頻率高的列上加,並且在重複列上加效果更好
索引不是越多越好,通常咱們在常出現於條件表達式中的列加索引.
值越分散的列,索引的效果越好
索引類型
primary key主鍵索引
Key 普通索引
unique key'惟一性索引
Email已經重複了,就不讓你加
索引長度:建索引時,只取前n個字符當作索引
多列索引 :就是把2列或多列的值的當成一個索引
冗餘索引 : 就是在某個列上,可能存在多個索引
好比xm(xing,ming) ming(ming)
索引操做:
查看:show index from t1 或者creat table t1
刪除:alter table t1 或者drop index m;
修改 alter table t1 add index/unique 索引名(列名)
事務:
必須選擇innodb---支持事務
①開啓事務 start transaction
②運行sql;
③提交,同時生效\回滾 commit\rollback
綜合練習:
鏈接上數據庫服務器
建立一個gbk編碼的數據庫
創建商品表和欄目表,字段以下:
商品表:goods
goods_id --主鍵,
goods_name -- 商品名稱
cat_id -- 欄目id
brand_id -- 品牌id
goods_sn -- 貨號
goods_number -- 庫存量
shop_price -- 價格
goods_desc --商品詳細描述
欄目表:category
cat_id --主鍵
cat_name -- 欄目名稱
parent_id -- 欄目的父id
建表完成後,做如下操做:
刪除goods表的goods_desc 字段,及貨號字段
並增長字段:click_count -- 點擊量
在goods_name列上加惟一性索引
在shop_price列上加普通索引
在clcik_count列上加普通索引
刪除click_count列上的索引
對goods表插入如下數據:
+----------+------------------------------+--------+----------+-----------+--------------+------------+-------------+
| goods_id | goods_name | cat_id | brand_id | goods_sn | goods_number | shop_price | click_count |
+----------+------------------------------+--------+----------+-----------+--------------+------------+-------------+
| 1 | KD876 | 4 | 8 | ECS000000 | 10 | 1388.00 | 7 |
| 4 | 諾基亞N85原裝充電器 | 8 | 1 | ECS000004 | 17 | 58.00 | 0 |
| 3 | 諾基亞原裝5800耳機 | 8 | 1 | ECS000002 | 24 | 68.00 | 3 |
| 5 | 索愛原裝M2卡讀卡器 | 11 | 7 | ECS000005 | 8 | 20.00 | 3 |
| 6 | 勝創KINGMAX內存卡 | 11 | 0 | ECS000006 | 15 | 42.00 | 0 |
| 7 | 諾基亞N85原裝立體聲耳機HS-82 | 8 | 1 | ECS000007 | 20 | 100.00 | 0 |
| 8 | 飛利浦9@9v | 3 | 4 | ECS000008 | 17 | 399.00 | 9 |
| 9 | 諾基亞E66 | 3 | 1 | ECS000009 | 13 | 2298.00 | 20 |
| 10 | 索愛C702c | 3 | 7 | ECS000010 | 7 | 1328.00 | 11 |
| 11 | 索愛C702c | 3 | 7 | ECS000011 | 1 | 1300.00 | 0 |
| 12 | 摩托羅拉A810 | 3 | 2 | ECS000012 | 8 | 983.00 | 14 |
| 13 | 諾基亞5320 XpressMusic | 3 | 1 | ECS000013 | 8 | 1311.00 | 13 |
| 14 | 諾基亞5800XM | 4 | 1 | ECS000014 | 4 | 2625.00 | 6 |
| 15 | 摩托羅拉A810 | 3 | 2 | ECS000015 | 3 | 788.00 | 8 |
| 16 | 恆基偉業G101 | 2 | 11 | ECS000016 | 0 | 823.33 | 3 |
| 17 | 夏新N7 | 3 | 5 | ECS000017 | 1 | 2300.00 | 2 |
| 18 | 夏新T5 | 4 | 5 | ECS000018 | 1 | 2878.00 | 0 |
| 19 | 三星SGH-F258 | 3 | 6 | ECS000019 | 0 | 858.00 | 7 |
| 20 | 三星BC01 | 3 | 6 | ECS000020 | 13 | 280.00 | 14 |
| 21 | 金立 A30 | 3 | 10 | ECS000021 | 40 | 2000.00 | 4 |
| 22 | 多普達Touch HD | 3 | 3 | ECS000022 | 0 | 5999.00 | 15 |
| 23 | 諾基亞N96 | 5 | 1 | ECS000023 | 8 | 3700.00 | 17 |
| 24 | P806 | 3 | 9 | ECS000024 | 148 | 2000.00 | 36 |
| 25 | 小靈通/固話50元充值卡 | 13 | 0 | ECS000025 | 2 | 48.00 | 0 |
| 26 | 小靈通/固話20元充值卡 | 13 | 0 | ECS000026 | 2 | 19.00 | 0 |
| 27 | 聯通100元充值卡 | 15 | 0 | ECS000027 | 2 | 95.00 | 0 |
| 28 | 聯通50元充值卡 | 15 | 0 | ECS000028 | 0 | 45.00 | 0 |
| 29 | 移動100元充值卡 | 14 | 0 | ECS000029 | 0 | 90.00 | 0 |
| 30 | 移動20元充值卡 | 14 | 0 | ECS000030 | 9 | 18.00 | 1 |
| 31 | 摩托羅拉E8 | 3 | 2 | ECS000031 | 1 | 1337.00 | 5 |
| 32 | 諾基亞N85 | 3 | 1 | ECS000032 | 1 | 3010.00 | 9 |
+----------+------------------------------+--------+----------+-----------+--------------+------------+-------------+
三 查詢知識
注:如下查詢基於ecshop網站的商品表(ecs_goods)
在練習時能夠只取部分列,方便查看.
1: 基礎查詢 where的練習:
查出知足如下條件的商品
1.1:主鍵爲32的商品
select goods_id,goods_name,shop_price
from ecs_goods
where goods_id=32;
1.2:不屬第3欄目的全部商品
select goods_id,cat_id,goods_name,shop_price from ecs_goods
where cat_id!=3;
1.3:本店價格高於3000元的商品
select goods_id,cat_id,goods_name,shop_price from ecs_goods
where shop_price >3000;
1.4:本店價格低於或等於100元的商品
select goods_id,cat_id,goods_name,shop_price from ecs_goods where shop_price <=100;
1.5:取出第4欄目或第11欄目的商品(不準用or)
select goods_id,cat_id,goods_name,shop_price from ecs_goods
where cat_id in (4,11);
1.6:取出100<=價格<=500的商品(不準用and)
select goods_id,cat_id,goods_name,shop_price from ecs_goods
where shop_price between 100 and 500;
1.7:取出不屬於第3欄目且不屬於第11欄目的商品(and,或not in分別實現)
select goods_id,cat_id,goods_name,shop_price from ecs_goods where cat_id!=3 and cat_id!=11;
select goods_id,cat_id,goods_name,shop_price from ecs_goods where cat_id not in (3,11);
1.8:取出價格大於100且小於300,或者大於4000且小於5000的商品()
select goods_id,cat_id,goods_name,shop_price from ecs_goods where shop_price>100 and shop_price <300 or shop_price >4000 and shop_price <5000;
1.9:取出第3個欄目下面價格<1000或>3000,而且點擊量>5的系列商品
select goods_id,cat_id,goods_name,shop_price,click_count from ecs_goods where
cat_id=3 and (shop_price <1000 or shop_price>3000) and click_count>5;
1.10:取出第1個欄目下面的商品(注意:1欄目下面沒商品,但其子欄目下有)
select goods_id,cat_id,goods_name,shop_price,click_count from ecs_goods
where cat_id in (2,3,4,5);
1.11:取出名字以"諾基亞"開頭的商品
select goods_id,cat_id,goods_name,shop_price from ecs_goods where goods_name like '諾基亞%';
1.12:取出名字爲"諾基亞Nxx"的手機
select goods_id,cat_id,goods_name,shop_price from ecs_goods
where goods_name like '諾基亞N__';
1.13:取出名字不以"諾基亞"開頭的商品
select goods_id,cat_id,goods_name,shop_price from ecs_goos
where goods_name not like '諾基亞%';
1.14:取出第3個欄目下面價格在1000到3000之間,而且點擊量>5 "諾基亞"開頭的系列商品
select goods_id,cat_id,goods_name,shop_price from ecs_goods where
cat_id=3 and shop_price>1000 and shop_price <3000 and click_count>5 and goods_name like '諾基亞%';
select goods_id,cat_id,goods_name,shop_price from ecs_goods where
shop_price between 1000 and 3000 and cat_id=3 and click_count>5 and goods_name like '諾基亞%';
1.15 一道面試題
有以下表和數組
把num值處於[20,29]之間,改成20
num值處於[30,39]之間的,改成30
mian表
+------+
| num |
+------+
| 3 |
| 12 |
| 15 |
| 25 |
| 23 |
| 29 |
| 34 |
| 37 |
| 32 |
| 45 |
| 48 |
| 52 |
+------+
1.16 練習題:
把good表中商品名爲'諾基亞xxxx'的商品,改成'HTCxxxx',
提示:大膽的把列當作變量,參與運算,甚至調用函數來處理 .
substring(),concat()
2 分組查詢group:
2.1:查出最貴的商品的價格
select max(shop_price) from ecs_goods;
2.2:查出最大(最新)的商品編號
select max(goods_id) from ecs_goods;
2.3:查出最便宜的商品的價格
select min(shop_price) from ecs_goods;
2.4:查出最舊(最小)的商品編號
select min(goods_id) from ecs_goods;
2.5:查詢該店全部商品的庫存總量
select sum(goods_number) from ecs_goods;
2.6:查詢全部商品的平均價
select avg(shop_price) from ecs_goods;
2.7:查詢該店一共有多少種商品
select count(*) from ecs_goods;
2.8:查詢每一個欄目下面
最貴商品價格
最低商品價格
商品平均價格
商品庫存量
商品種類
提示:(5個聚合函數,sum,avg,max,min,count與group綜合運用)
select cat_id,max(shop_price) from ecs_goods group by cat_id;
3 having與group綜合運用查詢:
3.1:查詢該店的商品比市場價所節省的價格
select goods_id,goods_name,market_price-shop_price as j
from ecs_goods ;
3.2:查詢每一個商品所積壓的貨款(提示:庫存*單價)
select goods_id,goods_name,goods_number*shop_price from ecs_goods
3.3:查詢該店積壓的總貨款
select sum(goods_number*shop_price) from ecs_goods;
3.4:查詢該店每一個欄目下面積壓的貨款.
select cat_id,sum(goods_number*shop_price) as k from ecs_goods group by cat_id;
3.5:查詢比市場價省錢200元以上的商品及該商品所省的錢(where和having分別實現)
select goods_id,goods_name,market_price-shop_price as k from ecs_goods
where market_price-shop_price >200;
select goods_id,goods_name,market_price-shop_price as k from ecs_goods
having k >200;
3.6:查詢積壓貨款超過2W元的欄目,以及該欄目積壓的貨款
select cat_id,sum(goods_number*shop_price) as k from ecs_goods group by cat_id
having k>20000
3.7:where-having-group綜合練習題
有以下表及數據
+------+---------+-------+
| name | subject | score |
+------+---------+-------+
| 張三 | 數學 | 90 |
| 張三 | 語文 | 50 |
| 張三 | 地理 | 40 |
| 李四 | 語文 | 55 |
| 李四 | 政治 | 45 |
| 王五 | 政治 | 30 |
+------+---------+-------+
要求:查詢出2門及2門以上不及格者的平均成績
## 一種錯誤作法
mysql> select name,count(score<60) as k,avg(score) from stu group by name having k>=2;
+------+---+------------+
| name | k | avg(score) |
+------+---+------------+
| 張三 | 3 | 60.0000 |
| 李四 | 2 | 50.0000 |
+------+---+------------+
2 rows in set (0.00 sec)
mysql> select name,count(score<60) as k,avg(score) from stu group by name;
+------+---+------------+
| name | k | avg(score) |
+------+---+------------+
| 張三 | 3 | 60.0000 |
| 李四 | 2 | 50.0000 |
| 王五 | 1 | 30.0000 |
+------+---+------------+
3 rows in set (0.00 sec)
mysql> select name,count(score<60) as k,avg(score) from stu group by name having k>=2;
+------+---+------------+
| name | k | avg(score) |
+------+---+------------+
| 張三 | 3 | 60.0000 |
| 李四 | 2 | 50.0000 |
+------+---+------------+
2 rows in set (0.00 sec)
#加上趙六後錯誤暴露
mysql> insert into stu
-> values
-> ('趙六','A',100),
-> ('趙六','B',99),
-> ('趙六','C',98);
Query OK, 3 rows affected (0.05 sec)
Records: 3 Duplicates: 0 Warnings: 0
#錯誤顯現
mysql> select name,count(score<60) as k,avg(score) from stu group by name having k>=2;
+------+---+------------+
| name | k | avg(score) |
+------+---+------------+
| 張三 | 3 | 60.0000 |
| 李四 | 2 | 50.0000 |
| 趙六 | 3 | 99.0000 |
+------+---+------------+
3 rows in set (0.00 sec)
#正確思路,先查看每一個人的平均成績
mysql> select name,avg(score) from stu group by name;
+------+------------+
| name | avg(score) |
+------+------------+
| 張三 | 60.0000 |
| 李四 | 50.0000 |
| 王五 | 30.0000 |
| 趙六 | 99.0000 |
+------+------------+
4 rows in set (0.00 sec)
mysql> # 看每一個人掛科狀況
mysql> select name,score < 60 from stu;
+------+------------+
| name | score < 60 |
+------+------------+
| 張三 | 0 |
| 張三 | 1 |
| 張三 | 1 |
| 李四 | 1 |
| 李四 | 1 |
| 王五 | 1 |
| 趙六 | 0 |
| 趙六 | 0 |
| 趙六 | 0 |
+------+------------+
9 rows in set (0.00 sec)
mysql> #計算每一個人的掛科科目
mysql> select name,sum(score < 60) from stu group by name;
+------+-----------------+
| name | sum(score < 60) |
+------+-----------------+
| 張三 | 2 |
| 李四 | 2 |
| 王五 | 1 |
| 趙六 | 0 |
+------+-----------------+
4 rows in set (0.00 sec)
#同時計算每人的平均分
mysql> select name,sum(score < 60),avg(score) as pj from stu group by name;
+------+-----------------+---------+
| name | sum(score < 60) | pj |
+------+-----------------+---------+
| 張三 | 2 | 60.0000 |
| 李四 | 2 | 50.0000 |
| 王五 | 1 | 30.0000 |
| 趙六 | 0 | 99.0000 |
+------+-----------------+---------+
4 rows in set (0.00 sec)
#利用having篩選掛科2門以上的.
mysql> select name,sum(score < 60) as gk ,avg(score) as pj from stu group by name having gk >=2;
+------+------+---------+
| name | gk | pj |
+------+------+---------+
| 張三 | 2 | 60.0000 |
| 李四 | 2 | 50.0000 |
+------+------+---------+
2 rows in set (0.00 sec)
4: order by 與 limit查詢
4.1:按價格由高到低排序
select goods_id,goods_name,shop_price from ecs_goods order by shop_price desc;
4.2:按發佈時間由早到晚排序
select goods_id,goods_name,add_time from ecs_goods order by add_time;
4.3:接欄目由低到高排序,欄目內部按價格由高到低排序
select goods_id,cat_id,goods_name,shop_price from ecs_goods
order by cat_id ,shop_price desc;
4.4:取出價格最高的前三名商品
select goods_id,goods_name,shop_price from ecs_goods order by shop_price desc limit 3;
4.5:取出點擊量前三名到前5名的商品
select goods_id,goods_name,click_count from ecs_goods order by click_count desc limit 2,3;
5 鏈接查詢
5.1:取出全部商品的商品名,欄目名,價格
select goods_name,cat_name,shop_price from
ecs_goods left join ecs_category
on ecs_goods.cat_id=ecs_category.cat_id;
5.2:取出第4個欄目下的商品的商品名,欄目名,價格
select goods_name,cat_name,shop_price from
ecs_goods left join ecs_category
on ecs_goods.cat_id=ecs_category.cat_id
where ecs_goods.cat_id = 4;
5.3:取出第4個欄目下的商品的商品名,欄目名,與品牌名
select goods_name,cat_name,brand_name from
ecs_goods left join ecs_category
on ecs_goods.cat_id=ecs_category.cat_id
left join ecs_brand
on ecs_goods.brand_id=ecs_brand.brand_id
where ecs_goods.cat_id = 4;
5.4: 用友面試題
根據給出的表結構按要求寫出SQL語句。
Match 賽程表
字段名稱 字段類型 描述
matchID int 主鍵
hostTeamID int 主隊的ID
guestTeamID int 客隊的ID
matchResult varchar(20) 比賽結果,如(2:0)
matchTime date 比賽開始時間
Team 參賽隊伍表
字段名稱 字段類型 描述
teamID int 主鍵
teamName varchar(20) 隊伍名稱
Match的hostTeamID與guestTeamID都與Team中的teamID關聯
查出 2006-6-1 到2006-7-1之間舉行的全部比賽,而且用如下形式列出:
拜仁 2:0 不來梅 2006-6-21
mysql> select * from m;
+-----+------+------+------+------------+
| mid | hid | gid | mres | matime |
+-----+------+------+------+------------+
| 1 | 1 | 2 | 2:0 | 2006-05-21 |
| 2 | 2 | 3 | 1:2 | 2006-06-21 |
| 3 | 3 | 1 | 2:5 | 2006-06-25 |
| 4 | 2 | 1 | 3:2 | 2006-07-21 |
+-----+------+------+------+------------+
4 rows in set (0.00 sec)
mysql> select * from t;
+------+----------+
| tid | tname |
+------+----------+
| 1 | 國安 |
| 2 | 申花 |
| 3 | 公益聯隊 |
+------+----------+
3 rows in set (0.00 sec)
mysql> select hid,t1.tname as hname ,mres,gid,t2.tname as gname,matime
-> from
-> m left join t as t1
-> on m.hid = t1.tid
-> left join t as t2
-> on m.gid = t2.tid;
+------+----------+------+------+----------+------------+
| hid | hname | mres | gid | gname | matime |
+------+----------+------+------+----------+------------+
| 1 | 國安 | 2:0 | 2 | 申花 | 2006-05-21 |
| 2 | 申花 | 1:2 | 3 | 公益聯隊 | 2006-06-21 |
| 3 | 公益聯隊 | 2:5 | 1 | 國安 | 2006-06-25 |
| 2 | 申花 | 3:2 | 1 | 國安 | 2006-07-21 |
+------+----------+------+------+----------+------------+
4 rows in set (0.00 sec)
6 union查詢
6.1:把ecs_comment,ecs_feedback兩個表中的數據,各取出4列,並把結果集union成一個結果集.
6.2:3期學員碰到的一道面試題
A表:
+------+------+
| id | num |
+------+------+
| a | 5 |
| b | 10 |
| c | 15 |
| d | 10 |
+------+------+
B表:
+------+------+
| id | num |
+------+------+
| b | 5 |
| c | 15 |
| d | 20 |
| e | 99 |
+------+------+
要求查詢出如下效果:
+------+----------+
| id | num |
+------+----------+
| a | 5 |
| b | 15 |
| c | 30 |
| d | 30 |
| e | 99 |
+------+----------+
create table a (
id char(1),
num int
)engine myisam charset utf8;
insert into a values ('a',5),('b',10),('c',15),('d',10);
create table b (
id char(1),
num int
)engine myisam charset utf8;
insert into b values ('b',5),('c',15),('d',20),('e',99);
mysql> # 合併 ,注意all的做用
mysql> select * from ta
-> union all
-> select * from tb;
+------+------+
| id | num |
+------+------+
| a | 5 |
| b | 10 |
| c | 15 |
| d | 10 |
| b | 5 |
| c | 15 |
| d | 20 |
| e | 99 |
+------+------+
參考答案:
mysql> # sum,group求和
mysql> select id,sum(num) from (select * from ta union all select * from tb) as tmp group by id;
+------+----------+
| id | sum(num) |
+------+----------+
| a | 5 |
| b | 15 |
| c | 30 |
| d | 30 |
| e | 99 |
+------+----------+
5 rows in set (0.00 sec)
7: 子查詢:
7.1:查詢出最新一行商品(以商品編號最大爲最新,用子查詢實現)
select goods_id,goods_name from
ecs_goods where goods_id =(select max(goods_id) from ecs_goods);
7.2:查詢出編號爲19的商品的欄目名稱(用左鏈接查詢和子查詢分別)
7.3:用where型子查詢把ecs_goods表中的每一個欄目下面最新的商品取出來
select goods_id,goods_name,cat_id from ecs_goods where goods_id in (select max(goods_id) from ecs_goods group by cat_id);
7.4:用from型子查詢把ecs_goods表中的每一個欄目下面最新的商品取出來
select * from (select goods_id,cat_id,goods_name from ecs_goods order by goods_id desc) as t group by cat_id;
7.5 用exists型子查詢,查出全部有商品的欄目
select * from category
where exists (select * from goods where goods.cat_id=category.cat_id);
建立觸發器:
CREATE trigger tg2
after insert on ord
for each row
update goods set goods_number=goods_number-new.num where id=new.gid
CREATE trigger tg3
after delete on ord
for each row
update goods set goods_number=good_number+old.num where id=old.gid
CREATE trigger tg4
after update on ord
for each row
update goods set goods_number=goods_number+old.num-new.num where id=old.gid