相關名詞
RDBMS
關系型數據庫
核心是以二維表存儲數據SQL
結構化查詢語言擂煞,用于關系型數據庫
不區(qū)分大小寫 select SELECT sELECT
重點是查詢MYSQL
關系型數據庫管理系統(tǒng)
開源层皱,免費,支持多平臺navical(客戶端) ---mysql(服務端妄讯,本地要在服務中啟動才行)
數據類型與約束
數據類型
- int :整數集峦,有符號(包括負數)和無符號(非負數)署辉,長度沒有意義
- varchar:字符串 ,字母和中文或數字都是一個字符
- decimal:小數
- decimal(3,1):小數點后1位汉规,整數2位
主鍵
`id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
或
`id` INT UNSIGNED AUTO_INCREMENT,
PRIMARY KEY ( `id` )
表操作
1.建表
create table 表名 (
鍵名 類型 約束,
鍵名 類型 約束
)
eg:
CREATE TABLE IF NOT EXISTS `runoob_tbl`(
`runoob_id` INT UNSIGNED AUTO_INCREMENT,
`runoob_title` VARCHAR(100) NOT NULL DEFAULT "我是默認值" COMMENT "注釋",
`submission_date` DATE,
PRIMARY KEY ( `runoob_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
UNSIGNED
:無符號的意思,可以理解為非負數 -
AUTO_INCREMENT
:定義列為自增的屬性驹吮,一般用于主鍵针史,數值會自動加1 -
NOT NULL、NULL
:是否可為空NULL -
DEFAULT "字符串"
:定義默認值 -
COMMENT "注釋"
:添加注釋 -
PRIMARY KEY
:關鍵字用于定義列為主鍵 -
ENGINE
: 設置存儲引擎 -
CHARSET
: 設置編碼
2碟狞、刪表
drop table 表名
drop table if exists 表名;#如果存在則刪除
增刪改
insert into 表名 values (值1,值2,值3);
insert into 表名 (字段1,字段2) values (值1,值2);
INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date)
VALUES ("學習 PHP", "菜鳥教程", NOW());
delete from 表名 where 條件
update 表名 set 字段1=新值1,字段2=新值2 where 條件
增:
- 不標明字段后邊全部值都要寫上误澳,標明字段桩了,后邊值對應上就行,不用在意順序
- 如果數據是字符型,必須使用單引號或者雙引號琢唾,如:"value"
刪:
- 如果沒有指定 WHERE 子句,MySQL 表中的所有記錄將被刪除
- 當你想刪除數據表中指定的記錄時 WHERE 子句是非常有用的
改:
- 當你需要更新數據表中指定行的數據時 WHERE 子句是非常有用的
查詢
select * from 表名
1巾钉、別名:as
select name as 姓名 国葬,sex as 性別 from stu
select name ,sex from stu as s
select s.name , s.sex, r.title from stu as s,runoob_tbl as r
- 給字段起別名,查詢結果表頭為別名
- 給表起別名(多個表之間的操作有意義)
查詢兩個表的時候未辆,如果兩個表有重復字段用別名窟绷,容易區(qū)分出來是哪個表里的字段
2、DISTINCT:過濾重復數據
select distinct 字段1咐柜,字段2 from 表名
- 若DISTINCT后邊字段為多個兼蜈,查詢結果:字段組合只要有一個不一樣就不算重復攘残,全部一樣才算重復數據,
[圖片上傳中...(image.png-9523a5-1607507995940-0)]
3为狸、條件查詢 where
select 字段 from 表名 where 條件
select * from stu not sex ='女'
select * from stu where name like "__"
select * from stu name in ('值1','值2','值3')#相當于下面or
select * from stu name= '值1' or name='值2' or name='值3'
select * from stu age between 18 and 20#18-20相當于下面and
select * from stu age>=18 and age<=20
#非
select * from stu not age between 18 and 20# 加not表示18-20之外
比較運算符
=
>
>=
<
<=
不等于!=
或<>
邏輯運算符
and
or
not
模糊查詢
like
%
表示任意多個字符
_
表示一個任意字符歼郭,兩個_
表示要有兩個任意字符范圍查詢
in
表示一個非連續(xù)的范圍內 ,相當于or
between A and B
表示在一個連續(xù)的范圍內辐棒,A必須<B 病曾,相當于and
空判斷
注意null
與''
是不同的,一個是空,一個是空字符串
判空is null
漾根、is not null
=null不可以
4泰涂、排序 order by
select * from 表名 order by 列1 asc,列2 desc
select * from stu order by convert(name using gbk)
- 先按字段1進行排序,如果字段1的值相同辐怕,在按照字段2排序逼蒙,以此類推
- 默認升序:ASC,可省略不寫
- 降序:DESC
- 中文排序:使用convert(name using gbk)轉換編碼utf8為gbk(漢字編碼字符集)
5寄疏、聚合函數
- 為了快速得到統(tǒng)計數據是牢,經常用到如下5個聚合函數
-
count(*/列名)
:
count(*)一條數據任何一個字段有值就會統(tǒng)計在內
count(列名)如果有null就不會統(tǒng)計在內 -
max(列名)
:表示此列的最大值 -
min(列名)
:表示此列的最小值 -
sum(列名)
:表示此列的和 -
avg(列名)
:表示求此列的平均值 - 聚合函數不能在
where
中使用
select count(*) from stu
6、分組
(1) 分組 group by
各有多少陕截,每種等字眼
select * from 表名 group by 列名
select sex,count(*) from stu group by sex
select class, sex,count(*) from stu group by sex,class
#統(tǒng)計每個班級中每種性別的同學人數
- 按照字段進行分組驳棱,表示此字段相同的數據會被放到一個組內
- 分組后,分組的依據列會在結果集中农曲,其他列不會顯示在結果集中
- 可以對分組后的數據進行統(tǒng)計社搅,做聚合運算
- 多個字段分組,字段組合一樣才是一個組的
(2) 分組后過濾數據 having
select 列1朋蔫,列2罚渐,聚合函數 from 表名 group by 列名 having 條件
select sex,count(*) from stu group by sex having sex='男'
- having 后面的條件運算和where的相同
- having 必須跟在group by 后邊才可以
(3) where having對比
- where :是對from后面指定的表進行數據篩選,屬于對原始數據的篩選--先篩選后分組
- having :是對group by的結果進行篩選 ---先分組后篩選
7驯妄、獲取部分行 limit
select * from 表名 limit start,count
select * from stu order by age limit 0,3
select * from stu limit 0,3
#和順序有關荷并,先排序在取前三行,因此上面兩個語句結果不一樣
select * from stu limit 3#取前三條
select * from stu order by age limit 1
#年齡最小的信息青扔,只適用于最小只有一人
- 當數據量非常大的時候在一頁中查看數據是一件非常麻煩的事情
- 從start開始源织,獲取count條數據
- start 索引從0開始
- 和順序是有關系的
- 簡寫省略的是start
8、連接查詢
(1) 等值連接 =
select * from 表1 as b1微猖,表2 as b2 where b1.字段=b2.字段
再有其他條件谈息,直接加在后邊即可
select * from stu,course,score
where stu.stuid=score.stuid and course.cid=score.cid
- 必須要出現后邊的等值條件,按照=的兩邊凛剥,取交集
- 不會出現新表侠仇,只是一個顯示結果
- 先連接成一個笛卡爾積(生成記錄總數=表1的總數*表2的總數),在根據條件篩選
- 會產生臨時表,占內存
(2) 內連接 inner join.....on.......
select * from 表1
inner join 表2 on 表1.字段=表2.字段
where 條件
order by .....
limit ....
select * from stu
inner join score on where stu.stuid=score.stuid
inner join course on course.cid=score.cid
where stu.name='王昭君'
#先兩個表連接逻炊,在和第三個表連接
#*要寫成列名時互亮,列名要加前綴表明是哪個表的,有重復的
#起別名余素,只能用別名
- 先根據條件篩選豹休,在連接兩個表
- 不會產生臨時表,不占內存桨吊,性能高一些
(3) 左連接
select * from 表1
left join 表2 on 表1.字段=表2.字段
select * from stu
left join score on where stu.stuid=score.stuid
#join前邊生成的結果作為左表
left join course on course.cid=score.cid
#查詢所有學生的成績威根,包括沒有成績的學生,需要顯示課程名
- join前面生成的結果作為左邊视乐,join后面的是右表洛搀,把左表的數據全部顯示
- 取左表所有結果,右表符合的連接炊林,沒有符合的就null
- 和內連接的區(qū)別就是姥卢,沒找到符合的不會顯示null,該條不會存在表中卷要,所以只要有右表不符合的情況渣聚,左表結果不會全部顯示
(4) 右連接
select * from 表1
right join 表2 on 表1.字段=表2.字段
select * from score
right join course on where course.cid=score.cid
left join stu on stu.stuid=score.stuid
#查詢所有課程的成績,包括沒有成績的課程僧叉,需要顯示學生信息
- join前面生成的結果作為左邊奕枝,join后面的是右表,把右表的數據全部顯示
- 取右表所有結果瓶堕,左表符合的連接隘道,沒有符合的就null
使用左右連接(題目中包含所有,沒有字眼需要用到左右連接)
- 只要明白那個是左表郎笆、右表谭梗;
- 那個需要所有結果;
- 那個需要null值宛蚓;
9激捏、自關聯
select * from areas as sheng,areas as shi
where sheng.aid=shi.pid
select * from areas as sheng,areas as shi,areas as qu
where sheng.aid=shi.pid and shi.aid=qu.pid
- 數據之間有上下級關系
- 在一個表中存儲所有數據
- 從一個表中查詢多次凄吏,必須起別名
10远舅、子查詢
-
()
里表示的是子查詢結果 - 子查詢返回的結果作為主查詢的條件:標量子查詢、行級子查詢痕钢、列級子查詢
- 子查詢返回的結果作為數據源:表子查詢
(1) 標量子查詢图柏,自查詢結果是一行一列
#查詢大于平均年齡的學生
select * from stu age>(select avg(age) from stu)
select * from stu age=(select min(age) from stu)
#查詢王昭君的成績,并顯示成績
select * from score where stuid=(select stuid from stu where name='王昭君')
(2) 列級子查詢任连,子查詢的結果是一列多行蚤吹,只能一列,用in
#查詢18歲的學生成績随抠,顯示成績
select * from score where stuid in (select stuid from stu where age=18)
(3) 行列級子查詢裁着,子查詢的結果是一行多列余佃,只能一行
select * from stu where sex='男' and age=26
#可以寫成
select * from stu where (sex,age)=('男',26)
#因此 ('男',26)里面兩個值可以寫成語句
select * from stu where (sex,age)=
(select sex,age from stu where sex='男' order by age limit 1)
#不大用,了解一下
(4) 表子查詢跨算,子查詢返回的結果是一個表爆土,多行多列
- 必須給子查詢部分起別名
select * from (select * from stu) as s
select * from 表1
inner join (可以是查詢出來的結果當作數據源使用) as 別名
on 表1.字段=表2.字段
where 條件
#查詢數據庫和系統(tǒng)測試的課程成績
select * from score
inner join (select * from course where cname in ('數據庫','系統(tǒng)測試')) as c
on score.cid=c.cid
#比起
select * from score
inner join course on score.cid=c.cid
where course.cname in ('數據庫','系統(tǒng)測試')
#性能高一點
(5) 子查詢中特定的關鍵詞使用
- in 范圍
- any| some 任意一個,格式:主查詢 where 列=any(列子查詢)
=any
等于=some
等于in
:等于子查詢返回的結果
>any
等于>some
:大于子查詢返回的結果中任意一個值诸蚕,就是大于最小值
<any
等于<some
:小于子查詢返回的結果中任意一個值步势,就是小于最大值
!=any|some
:沒有意義,就是查了所有 - all 所有背犯,格式: 主查詢 where 列<>all(列子查詢)
>all
:大于子查詢返回的結果中所有值坏瘩,就是大于最大值
<all
:小于子查詢返回的結果中所有值,就是小于最小值
!=all <>all
:不等于子查詢返回的結果中所有值漠魏,就是非
=all
:沒有意義倔矾,一個值不可能同時等于多個值
select * from score where stuid>any(select stuid from stu where age=18)
select * from score where stuid>all(select stuid from stu where age=18)
練習:
1.查詢所有價格大于平均價格(保留2位小數)的商品,并按價格降序排序
select * from goods where price>
(select round(avg(price),2) from goods ) order by price desc
- 查詢價格大于或等于“超極本”價格的商品柱锹,并按價格降序排序
子查詢返回的是一列多行
select * from goods where price >=any
(select price from goods where cate='超極本' ) order by price desc