MySQL 增改刪查、多表查詢


 

mysql關鍵字不區分大小寫
 

數據庫、數據表常用操作

show databases;  --查看所有的數據庫
use db_student;  --操作某個數據庫之前要先用use指定要使用數據庫

show tables;  #查看當前數據庫中的表

 

記錄的增改刪查

select id,username,tel from tb_user;
select * from tb_user;


insert into tb_user (username,tel) values ('chy','188xxxxx'; 

insert into tb_user (username,tel) values ('chy1,'188xxxx'),('chy2','187xxxxx');  --同時插入多條記錄,()之間逗號隔開

insert into tb_user values ('chy','188xxxxx');  --插入所有字段時可不指定字段名


update tb_user set username='chy',age=20 where id=1
update tb_user set age=age+2 where id=1;  --在原值的基礎上修改


delete from tb_user where id=1

字符串、日期時間類型的值要引起來,mysql不分區單雙引

 

where子句

where id=1

where id<>1  --  <>是關係數據庫通用的不等號
where id!=1  --mysql也可以用!=

--  >   >=   <   <=


where id between 1 and 10  -- [1,10],閉區間

where id in(1,3,9)  -- id=1或id=3或id=9


where id < all(1,3,9)  -- id要小於集合中的任何一個元素
where id < all(select id from tb_user where age<20)  -- 一般和子查詢搭配使用

where id <any(1,3,9)  #id小於集合中的任意一個元素即可,id可以是[1,8]。一般和子查詢搭配使用


where score>60 and score<90
where score<60 or score>90
where dep not in ("cs","math")  -- not表示非,常和其它關鍵字搭配使用


where score is null 
where score is not null  -- 不能直接not null


-- 模糊匹配
where name like '張%'  --以張開頭
where name like '%偉'  --以偉結尾
where name like '%國%' --含有國

%  -- 一個或多個字符
_  -- 任意一個字符

[abcd]  -- abcd中的任意一個字符,[]只代表一個字符,eg. '張[傑偉]' 匹配張傑、張偉
[!abcd]  -- 只要不是abcd中的任意一個字符就行,eg. '張[!傑偉]'  只要不是張傑、張偉就ok
[^abcd]  -- !也可以寫成^

 

查詢常用

select distinct username from tb_user;  -- distinct 去重,如果結果集中有完全相同的記錄,只保留一條

select price*number from tb_order_item where id=1;  -- 數值型可以進行數學運算



-- 聚合函數:對結果集進行統計、分析的函數。在聚合函數中,值是null的記錄不參與統計
select count(*) from tb_user;  -- 記錄總數
select count(username) from tb_user;  -- 某一列的記錄數
select count(distinct username) from tb_user;  -- 去重,重複的記錄只算做一條

select max(age) from tb_user;
select min(age) from tb_user;

select sum(score) from tb_student;
select avg(score) from tb_student;

select first(username) from tb_user;  -- 該列的第一個值

select last(username) from tb_user;  -- 該列的最後一個值

select sum(score)avg(score) from tb_student;  -- 可一起使用



-- 其它常用函數,as不能省略
select if(gender,'男','女') as gender from tb_user;  -- 相當於三元運算符

select ifnull(money,0) as money from tb_user;  -- 如爲空,返回設置的默認值



-- order by子句,結果集排序
select * from tb_user order by age;  -- 默認按升序(asc)排列
select * from tb_user order by age desc;  -- desc降序
select * from tb_user order by name,age desc;  -- 多個排序關鍵字,前面的關鍵字字段值相同時,使用後面的關鍵字排序



-- group by 子句,結果集分組
select * from tb_student group by dep;  -- 把dep相同的記錄分爲一組,返回的是分好的組,不是記錄

select count(*from tb_student group by dep;  -- 統計每個系的學生人數。單獨使用group by意義不大,一般搭配聚合函數使用,統計每組的數據
select avg(score) from tb_student group by class;  -- 統計每個班的平均分



-- having子句,一般和group by搭配使用,用來對分組進行過濾
select * from tb_student [where子句] group by class having class between 0 and 9; #查詢[1,10]班的學生信息
-- group by後面不能使用where,且where子句中不能直接使用聚合函數,having用於彌補where的不足
-- group by以哪個字段進行分組,having就只能以哪個字段進行過濾,把不符合要求的組去掉



-- 分頁,常見的分頁方式有三種
-- 1、where限制區間,eg.where id>0 and where id<10
-- 2、limit
-- 3、返回全部記錄,由客戶端實現分頁,在結果集可能很大的情況下不推薦使用,內存、時間開銷大

-- limit 結果集分頁。oracle是top
select * from tb_user [where子句] [order by子句] limit 10;  #只返回結果集的前10條記錄
select * from tb_user [where子句] [order by子句] limit 9,19;  #只返回結果集的第[10,20]條記錄。都+1,再取閉區間



-- 多個子句的書寫、執行順序
select ... from ... [where子句]  [group by子句]  [having子句]  [order by子句]  [limit子句]
-- 先執行select ... from ...  [where子句] ,將匹配的記錄放到結果集中
-- 再group by對結果集中的記錄進行分組
-- having對分組進行過濾,去掉不滿足條件的分組
-- orderby排序
-- limit只取出結果集的某個區間,返回給客戶端


-- 常用的
select ...  from ...  [where子句]  [group by子句]  [having子句]
select ...  from ...  [where子句]  [order by子句]  [limit子句]


-- 別名
select username as '用戶名' from tb_user;   -- 字段別名,返回時用別名替換字段名
select tu.username from tb_user tu;  -- 表別名,常用於多表查詢

 

多表查詢

union 結果集合並

如果多個select分別查表,select取的字段數、字段名、字段類型相同,可以使用union把多個結果集合併爲一個結果集。
一個select返回m條記錄,另一個select返回n條記錄,合併之後就是m+n條記錄

-- 查詢全校師生的id、name

-- union默認會去重,如果合併得到的結果集中有重複的記錄,只保留一條,distinct可以缺省
select id,name from tb_student union [distinct] select id,name from tb_teacher;  

-- all,保留全部記錄,不去重
select id,name from tb_student union all select id,name from tb_teacher;   

-- 如果要合併多個結果集,兩兩之間union連接
select語句1 union [distinct|all] select語句2 union [distinct|all] select語句3 ...

 

子查詢

-- 在where中使用子查詢
-- eg.有2張表,tb_dep 一條記錄即一個系的信息,tb_student 一條記錄即一個學生的信息,查詢計算系所有學生的學號、姓名
select id,name from tb_student where dep_id=(select id from tb_dep where dep_name='計算機系'); 



-- 在having中使用子查詢
-- eg. 查詢大於平均分的學生成績
select * from tb_score group by id having score>(select avg(score) from tb_score)-- group by 主鍵,按主鍵分組,一個分組就是一條記錄,對分組的過濾就是對記錄的過濾


-- where、having的過濾中有2個常用關鍵字:any、all
where xxx > any(子查詢)  #大於任一個即可
where xxx > all(子查詢)  #大於所有才行



-- 在from中使用子查詢
select 列名 from (select子查詢);  -- 把子查詢的結果集作爲一張臨時表

select 列名 fromselect子查詢)[別名] [子句]-- 臨時表的使用方式和表名一樣

 

join 連接查詢

笛卡爾積

2個集合相乘,得到的是笛卡爾積

{A,B,C} * {a,b,c} = { (A,a)(A,b)(A,c)(B,a)(B,b)(B,c)(C,a)(C,b)(C,c) } 

即用一個集合的每個元素去乘另一個集合的每個元素

 

sql99 連接查詢語法

select1中的列,2中的列  from1 [別名]  [連接類型] join2 [別名] on 連接條件

[where子句]

[group by子句]

[having子句]

[order by子句]

[limit子句]

sql 99的連接查詢帶有關鍵字join,稱之爲顯式寫法。在sql 99之前還有一個sql語法版本:sql 92,顧名思義,92年制定的標準。sql 92的連接查詢不帶join,也具有相同的功能,現在還能用,稱之爲隱式寫法。

 

根據連接類型可以把連接查詢分爲4類

  • 交叉連接
  • 內連接:又分爲等值連接、非等值連接、自連接
  • 外連接:又分爲左外連接(左連接)、右外連接(右連接)、全外連接(全連接,mysql不支持,oracle支持)
  • 自然連接
     

假設tb_student有30條記錄,tb_score有20條記錄(10人因缺考、緩考等原因暫時沒有成績)

-- 交叉連接,得到的是笛卡爾積,基本不用
select st.*,sc.* from tb_student st cross join tb_score sc;
select * from tb_student cross join tb_score;  -- 可以用一個*表示多表的所有字段
-- 30*20=600,返回600條記錄




-- 內連接,以少的爲準(2張表中都要有)
select * from tb_student st [inner] join tb_score sc on st.id=sc.student_id;  -- join默認就是內連接,inner可以缺省
-- 只返回20條記錄,成績爲空的10人不要了

-- on指定2張表的連接條件(關聯關係),使用on對笛卡爾積中的記錄進行篩選。如果是單張表的條件,比如 st.id>10,寫在where中

-- 等值連接:on中使用等號進行篩選、判斷
-- 非等值連接:on中使用>、>=、<、<=、between and...連接2張表(不使用等號)



-- 內連接的隱式寫法
select * from tb_student st,tb_score sc where st.id=sc.student_id;  -- 在where中指定連接條件



-- 內連接之自連接
-- 顧名思義,自己連接自己進行查詢。有時候表是關聯到自身的,需要連接自身來查詢
-- eg. 員工表,員工和直屬上司都是員工,都在一張表裏。查詢員工信息及其直屬上司的姓名,superior_id是直屬上司的id
select te1.*,te2.name as superior_name from tb_employees te1 [inner] join tb_employees te2 where te1.superior_id=te2.id;
-- 都是同一張表,取不同的別名來區分




-- 外連接
-- 內連接以少的爲準(作爲主表),外連接可以指定以哪張表爲準(作爲主表),更靈活
select * from tb_student st left [outer] join tb_score sc on st.id=sc.student_id;
-- outer可以省略不寫,left是左外連接,right是右外連接,full是全外連接(mysql不支持,oracle支持)

-- 左外連接以join左邊的表爲準(主表),右外連接以join右邊的表爲準,全連接是2張表的記錄都保留(在另一張表中找不到對應|關聯的記錄都保留)。




-- 自然連接
-- 自然連接可以看做是一種特殊的等值連接,會自動把2張表中相同的列(列名、數據類型都要相同)作爲連接條件
select * from tb_student natural join tb_score;
-- 比如兩張表都有id字段,會自動添加連接條件 on 表1.id=表2.id




-- 多張表,寫多個join就行
select1的字段,2的字段,3的字段 from1 [別名]
left join2 [別名] on1.id=2.id
left join3 [別名] on2.id=3.id
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章