Mysql基礎
阿新 • • 發佈:2020-02-06
Mysql學習筆記
一、資料庫的基本概念
- DB 資料庫(database):儲存資料的“倉庫”,它儲存了一系列有組織的資料。
- DBMS 資料庫管理系統 (Database ManagementSystem)。資料庫是通過DBMS建立和操作的容器。
- SQL 結構化查詢語言 (Structure Query Language),專門用來和資料通訊的語言。
SQL的優點
- 不是某個資料庫供應商特有的專用語言,幾乎所有DBMS都支援SQL
- 簡單易學
- 雖然簡單,但實際上是一種強有力的語言,靈活使用其語言元素,可以進行非常複雜和高階的操作。
資料庫的特點
- 將資料放到表中,表再放到資料庫中。
- 一個數據庫可以有多張表,每個表都有一個名字,用來標識自己,表名具有唯一性。
- 表由列組成,我們也稱為欄位,所有表都是由一個或多個列組成的。
- 表中的資料是按行儲存的。
Mysql 語法規範
- 不區分大小寫,但建議關鍵字大寫,表名、列名小寫;
- 每條命令最好用分號結尾;
- 每條命令根據需要,可以進行縮排或換行;
- 註釋
單行註釋:#註釋文字
單行註釋:-- 註釋文字
多行註釋:/註釋文字/
二、DQL語言
進階一:基礎查詢
語法
select 查詢列表 from 表名;
- 特點
查詢列表可以是:表中的欄位、常量值、表示式、函式
查詢的結果是一個虛擬的表格
use employees;#查詢前需要先開啟資料庫
#查詢表中單個欄位
select last_name from employee;
#查詢表中多個欄位
select last_name,salary,email from employees;
#查詢表中所有欄位
select * from employees;
查詢常量值
select 100; select 'john'; #查詢表示式 select 100*98; #查詢函式 select version(); #起別名(便於理解;如果查詢的欄位有重名的情況,使用別名可以區分開來) 方式一:使用as select 100*98 as 結果; select last_name as 姓,first_name as 名 from employees; 方式二:使用空格 select last_name 姓,first_name 名 from employees; #注:別名中有關鍵字等特殊符號,需要將別名用引號引起來 select salary as "out put" from employees; #去重 #案例 查詢員工表中涉及到的所有的部門編號 select distinct department_id from employees;
+號作用
# mysql中的+號,僅僅只有一個功能:運算子
select 100+90;兩個運算元都為數值型,則做加法運算
select '100'+90; 只要其中一方為字元型,試圖將字元型轉換為數值型
如果轉換成功,則繼續做加法運算
select 'john'+90 如果轉換失敗,則將字元型數值轉換為0
select null+90; 如果其中一方為null,則結果肯定為null
# 案例:查詢員工名和員工姓連線成一個欄位,並顯示為 姓名
select concat(first_name,last_name) as 姓名 from employees;
#顯示錶結構
desc department;
進階二:條件查詢
select 查詢列表 from 表名 where 篩選條件;
篩選條件分類:
- 按條件表示式篩選
條件運算子 > < = != <> >= <= - 按邏輯表示式篩選
邏輯運算子 and or not
作用:用於連線條件表示式 - 模糊查詢
like
between and
in
is null
按條件表示式查詢
#案例1 :查詢工資>12000 的員工資訊
select * from employees where salary>12000;
#案例2:查詢部門編號不是90的員工姓名和部門編號
select
last_name,department_id
from
employees
where
department_id != 90;
按邏輯表示式查詢
# 案例1:查詢工資在10000到20000之間的員工名、工資及獎金
select
last_name,commission
from
employees
where
salary>=10000 and salary<=20000;
#案例2:查詢部門編號不在90-110之間,或者工資高於15000的員工資訊
select
*
from
employees
where
not(department_id>=90 and department_id<=110) or salary>=15000;
模糊查詢
- like
特點:1.一般和萬用字元搭配使用
2. % 任意多個字元
3. _任意單個字元
#案例1:查詢員工名中包含字元a的員工資訊
select
*
from
employees
where
last_name like '%a%';
#案例2:查詢員工名中第三個字元為n,第五個字元為m的員工名和工資
select
last_name,salary
from
employees
where
last_name like '__n_m%';
#案例3:查詢員工名中第二個字元為_的員工名
select
last_name
from
employees
where
last_name like '_\_%';
- between and
特點:1.使用between and 可以簡化查詢語句
2.包含臨界值
3.兩個臨界值不要調換順序
#案例:查詢員工編號在100到200之間的員工資訊
select
*
from
employees
where
employee_id>=100 and employee_id<=200;
---------------------------------------------------------------
select
*
from
employees
where
employee_id between 100 and 200;
- in
含義:判斷某欄位的值是否屬於in列表中的某一項
特點:1. 使用in比使用or提高了語句簡潔度
2. in列表的值型別必須統一或者相容
#案例:查詢員工的工種編號是vp,vn,vc的員工姓名和工種編號
select
last_name,job_id
from
employees
where
job_id = 'vp' or job_id = 'vn' or job_id = 'vc';
---------------------------------------------------
select
last_name,job_id
from
employees
where
job_id in ('vp','vn','vc');
- is null
1.= 或者<>不能用來判斷null
2.is null 或者is not null可以進行判斷
#案例:查詢沒有獎金的員工名和獎金率
select
last_name,commission_pct
from
employees
where
commission_pct is null;
- 安全等於 <=>
#案例1:查詢沒有獎金的員工名和獎金率
select
last_name,commission_pct
from
employees
where
commission_pct <=> null;
# 案例2:查詢工資為12000的員工資訊
select
*
from
employees
where
salary <=>12000;
is null pk <=>
- is null :僅僅可以判斷null值,可讀性較高,建議使用;
- <=> :既可以判斷null值,又可以判斷普通的數值,可讀性較低。
進階三:排序查詢
#語法:
select 查詢列表
from 表
(where 篩選條件)
order by 排序列表 (asc | desc)
- 特點:1.desc 降序排列
2. asc 升序排列 不寫預設升序排列
3.order by 子句中可以支援單個欄位、多個欄位、表示式、函式、別名
4.order by 一般放在查詢語句的最後面,limit子句除外
# 案例1:查詢部門編號大於90 的員工資訊,按照入職時間先後進行排列(添加了篩選條件)
select *
from employees
where department_id >=90
order by hiredate asc;
#案例2:按年薪的高低顯示員工資訊和年薪
select *,salary*12*(1+ifnull(commission_pct,0)) as 年薪
from employees
order by salary*12*(1+ifnull(commission_pct,0)) desc;
【按別名排序】
#案例3:按年薪的高低顯示員工資訊和年薪
select *,0)) as 年薪
from employees
order by 年薪 desc;
【按函式排序】
# 案例4:按姓名的長度顯示員工的姓名和工資
select length(last_name) 位元組長度,last_name,salary
from employees
order by length(last_name) desc;
【按多個欄位排序】
# 查詢員工資訊,先按照工資進行升序,再按照部門編號降序排列
select *
from employees
order by salary asc,employee_id desc;
進階四:常見函式
- 概念:類似於Java中的方法,將一組邏輯語句封裝在方法中,對外暴露方法名
- 好處:1.隱藏了實現細節 2.提高程式碼的重用性
呼叫函式:select 函式名(實參列表)【from 表】 - 特點:1.叫什麼(函式名) 2.幹什麼(函式功能)
- 分類:1.單行函式 如 concat、length、ifnull
2.分組函式 做統計使用又稱為統計函式、聚合函式、組函式
字元函式
- length 函式 獲取引數值得位元組個數
select length('john');
select length('張三丰hahahha')
#返回值 15 注 一個字母代表一個位元組,一個漢字代表三個位元組
- .concat 拼接字串
select concat(first_name,'_',last_name)
from employees;
- upper、lower
select upper('john');
# 示例 將姓大寫,名小寫,並進行拼接
select concat(upper(last_name),lower(first_name)) as 姓名
from employees;
- substr substring
注意:索引從1開始
#擷取從指定索引處後面的所有字元
select substr('李莫愁愛上了陸展元',7);
#擷取從指定索引處的字元長度的字元
select substr('李莫愁愛上了陸展元',1,3);
#案例:姓名中首字母大寫,其它字元小寫然後用_拼接,顯示出來
select concat(upper(substr(last_name,1),'_'lower(substr(last_name,2))) as 姓名
from employees;
- instr
#返回子串第一次出現的索引,如果找不到返回0
select instr('楊不悔愛上了殷六俠','殷六俠');
- trim
#刪除字元兩端的空格或字元
select trim(' 張翠山 ') as output;
select trim('a','aaaaa張翠山aaaa') as putputl
- lpad
#用指定的字元實現左側填充指定的長度
select lpad('殷素素',10,*) as output;
- rpad
#用指定的字元實現左側填充指定的長度
select rpad('殷素素',12,ab) as output;
- replace
#用指定字元去替換字元中的指定字元
select replace('周芷若愛上了張無忌','周芷若','張無忌') as output;
數學函式
- round 四捨五入
select round(1.57);
select round(1.567,2);
- ceil 向上取整
# 返回大於該引數的最小整數
select ceil(1.002);
- floor 向下取整
select floor(9.99);
- truncate 截斷 截斷並保留小數點後指定位數
select truncate(1.5888,1);
#返回值為1.5,不進行四捨五入,進行截斷
- mod 取餘
select mod(10,3);
日期函式
- now 返回當前系統日期+時間
select now();
- curdate 返回系統當前日期,不包含時間
select curdate();
- curtime 返回當前時間,不包含日期
select curtime();
- 可以獲取指定的部分,年year、月month、日day、小時hour、分minute、秒second
select year(now()) as 年;
select year('2020-1-20') as 年;
#返回月份的英文
select monthname(now()) as 月;
- str_to_date : 將日期格式的字元轉換成指定格式的日期
select str_to_date('2020-2-1','%Y-%c-&d');
- date_format :將日期轉換成字元
#查詢有獎金的員工姓名和入職日期,日期顯示格式為 xx月xx日 xx年
select last_name,date_format(hiredate,%m月%d日 %y年)
from employees
where employee_pct is not null;
其它函式
# 檢視版本號
select version();
#檢視有哪些資料庫
select databases();
#檢視使用者
select user();
流程控制函式
- if 函式 類似if else的效果
select last_name,if(salary is null,'沒工資,呵呵','有工資,嘻嘻')
from employees;
進階五:分組函式
- 功能:用作統計使用,又稱為聚合函式或統計函式或函式組。
- 分類:sum 求和、avg 平均值 、max 最大值、min 最小值、count 計數
- 簡單的使用:
select sum(salary) from employees;
select max(salary) from employees;
select min(salary) from employees;
select avg(salary) from employees;
select count(salary) from employees;
select sum(salary) 總工資,max(salary) 最高,avg(salary) 平均值
from employees;
- 引數支援的型別
1、sum、avg一般用於處理數值型
2、 max、min、count可以處理任何型別
3、可以和distinct搭配使用實現去重
4、以上分組函式都忽略null值 - count函式的詳細介紹
select count(salary) from employees;
select count(*) from employees;
select count(1) from employees;
select count('崔霞') from employees;
- count函式的單獨介紹
一般使用count(*)用作統計行數 - 和分組函式一同查詢的欄位要求是group by後的欄位
進階六:分組查詢
- 語法
select 分組函式,列(要求出現在group by的後面)
from 表名
【where 篩選條件】
group by 分組的列表
【order by 子句】
注:查詢列表比較特殊,要求是分組函式和group by後出現的欄位
特點:分組查詢中的篩選條件分為兩類
1.分組前篩選 資料來源為原始表 , 位置在group by子句的前面 , 關鍵字為where
2.分組後篩選 資料來源為分組後的結果集 ,位置在group by子句的後面 , 關鍵字為having
- 分組函式做條件肯定是放在having子句中
- 能用分組前篩選的,優先使用分組前篩選
- group by 子句支援單個欄位分組,多個欄位分組(多個欄位之間用逗號隔開沒有順序要求),表示式或者函式(用的較少)
- 也可以新增排序(放在整個的分組查詢的最後)
#簡單的分組查詢
# 查詢每個工種的最高工資
select max(salary),job_id
from employees
group by job_id;
#查詢每個位置上的部門個數
select count(*),location_id
from employees
group by location_id;
#查詢郵箱中包含字母a,每個部門的平均工資
select avg(salary),department_id
from employees
where email like '%a%
group by department_id;
#查詢每個領導手下員工的最高工資
select max(salary),manager_id
from employees
where commission_pct is not null
group by manager_id;
- 新增分組後的篩選條件(having子句的使用)
#案例1:查詢哪個部門的員工數>2
select count(*),department_id
from employees
group by department_id
having count(*)>2;
案例2:查詢每個工種有獎金的員工的最高工資>12000的工種編號和最高工資
select max(salary),job_id
from employees
where commission_pct is not null
group by job_id
having max(salary)>12000;
#案例3:查詢每個領導編號大於102的員工的最低工資大於5000的領導編號和最低工資
select min(salary),manager_id
from employees
where manager_id>102
group by manager_id
having min(salary)>5000;
- 按表示式或函式分組
# 案例: 按員工姓名的長度分組,查詢每一組的員工個數,篩選員工個數>5的有哪些
select count(*)
from employees
group by length(last_name)
having count(last_name);
- 按多個欄位分組
#查詢每個部門每個工種的員工的平均工資
select avg(salary),department_id,job_id
from employees
group by department_id,job_id;
- 新增排序
#查詢每個部門每個工種的員工的平均工資,並篩選出平均工資大於10000的從高到低排序
select avg(salary).department_id,job_id
from employees
where department_id is not null
group by department_id,job_id
having avg(salary)>10000
order by avg(salary) desc;
- 練習
# 查詢各job_id的員工的工資的最大值、最小值、平均值、總和,並按job_id升序
select max(salary),min(salary),avg(salary),sum(salary),job_id
from employees
group by job_id
order by job_id;
# 查詢員工最高工資和最低工資的差距(difference)
select max(salary)-min(salary) difference
from employees;
#查詢各個管理者手下員工的最低工資,其中最低工資不能低於6000,沒有管理者的員工不計算在內
select min(salary),manager_id
from employeers
where manager_id is not null
group by manager_id
having min(salary)>=6000;
#查詢所有部門的編號、員工數量和工資平均值,並按平均工資降序
select department_id,count(*),avg(salary)
from employees
group by department_id
order by avg(salary) desc;
#選擇具有各個job_id的員工人數
select count(*) 個數,job_id
from employees
group by job_id;
進階七:連線查詢
- 含義:又稱多表查詢,當需要用到兩個表的時候
- 笛卡爾乘積現象:表1有m行,表2有n行,結果=m*n行
如何避免:新增有效的連線條件 - 分類:按年代分類 sql92標準(僅僅支援內連線)、sql99標準(推薦使用)
按功能分類:內連線(分為等值連線、非等值連線、自連線)、外連線(左外連線、右外連線、全外連線)、交叉連線 - 等值連線
特點:多表等值連線的結果為多表的交集部分;
n表連線至少需要n-1個連線條件;
多表的順序沒有要求;
一般需要為表起別名;
可以搭配前面介紹的所有子句使用,比如排序、分組、篩選
#查詢員工名和對應的部門名
select last_name,department_name
from employees,departments
where employees.'department_id'=departments.'department_id';
- 為表起別名
好處:提高語句的簡潔度,區分多個重名的欄位
如果為表起了別名,則查詢的欄位就不能使用原來的表名去限定
#查詢員工名、工種號、工種名
select e.last_name,e.job_id,j.job_title
from employees e,jobs j
where e.'job_id'=j,'job_id';
- 可以加篩選
#查詢有獎金的員工名、部門名
select last_name,department_name
from employees e,department f
where e.'department_id'=f.'department_id'
and e.'commission_pct' is not null;
#查詢城市名中第二個字元為o的部門名和城市名
select department_name,city
from departments d,location l
where d.'location_id' = l.'location_id'
and city like '_o%';
- 可以加分組
#查詢每個城市的部門個數
select count(*) 個數
from departments d,locations l
where d.'location_id' = l.'location_id'
group by city;
#查詢有獎金的每個部門的部門名和部門的領導編號和該部門的最低工資
select department_name,d.'manager_id',min(salary)
from department d,employees e
where d.'department_id' = e.'department_id'
and commission_pct is not null
group by department_name,d.'manager_id';
- 可以加排序
#查詢每個工種的工種名和員工的個數,並且按照員工個數降序
select job_title,count(*)
from employees e,jobs j
where e.'job_id' = j.'job_id'
group by job_title
order by count(*) desc;
- 實現三表連線
#查詢員工名、部門名和所在城市
select last_name,department_name,city
from employees e,department d,location l
where e.'department_id' = d.'department_id' and d.'location_id' = l.'location_id';
- 非等值連線
# 查詢員工的工資和工資級別
select salary,grade_level
from employees e,job_grade g
where salary between g.'lowest_sal' and g.'highest_sal';
- 練習
#顯示員工表的最大工資、工資平均值
select max(salary),avg(salary) from employees;
# 查詢員工表的employees_id,job_id,last_name,按department_id 降序,salary升序
select employees_id,last_name from employees order by department_id desc,salary asc;
#查詢員工表的job_id中包含a和e,並且a在e的前面
select job_id from employeees where job_id like %a%e%;
#顯示當前日期、以及去前後空格,擷取子字串函式
select now();
select trim();
select substr();
- sql99語法
- 內連線
- 外連線
- 語法
#語法
select 查詢列表
from 表1 別名 【連線型別】
join 表2 別名
on 連線條件
【where 篩選條件】
【group by 分組】
【order by 排序列表】
- 分類
內連線:inner
外連線 :左外 left outer、右外 right outer 、全外 full outer
交叉連線 cross - 內連線
#語法
select 查詢列表
from 表1 別名
inner join 表2 別名
on 連線條件
- 分類: 等值、非等值、自連線
#等值連線
#案例1:查詢員工名、部門名
select last_name,department_name
from employees e
inner join departments d
on e.'department_id'=d.'department_id';
#案例2:查詢名字中包含e的員工名和工種名【新增篩選】
select last_name,job_title
from employees e
inner join jobs j
on e.'job_id'=j.'job_id'
where e.'last_name' like '%e%';
#案例3:查詢部門個數大於3的城市名和部門個數【新增分組和篩選】
select city,count(*) 部門個數
from departments d
inner join locations l
on d.'location_id'=l.'location_id'
group by city
having count(*)>3;
#案例4:查詢哪個部門的員工個數大於3的部門名和員工個數,並按個數降序【新增排序】
select count(*),department_name
from employees e
inner join department d
on e.'department_id'=d.'department_id'
group by department_name
having count(*)>3
order by count(*) desc;
#案例5:查詢員工名、部門名、工種名,並按部門名降序【新增三表排序】
select last_name,job_title
from employees e
inner join departments d on e.'department_id'=d.'department_id'
inner join jobs j on e.'job_id'= j.'job_id'
order by department_name desc;
- 特點:新增排序 、分組篩選;inner可以省略;篩選條件放在where後面,連線條件放在on後面,提高分離性,便於閱讀;inner join連線和sql92語法中的等值連線效果是一樣的,都是查詢多表的交集。
- 非等值連線
#查詢員工工資級別
select salary,grade_level
from employees e
join job_grades g
on e.'salary'between g.'lowest_sal' and g.'higest_sal';
#查詢工資級別的個數>20的個數,並且按照工資級別降序
select count(*),grade_level
from employees e
join job_grades g
on e.'salary'between g.'lowest_sal' and g.'highest_sal'
group by grade_level
having count(*)>20
order by grade_level desc
- 外連線
應用場景:用於查詢一個表中有,另一個表中沒有的記錄
進階八:子查詢
- 含義:出現在其它語句中的select語句,稱為子查詢或內查詢;外部的查詢語句,稱為主查詢或外查詢
- 分類:按子查詢出現的位置:select後面(僅僅支援標量子查詢)、from後面(支援表子查詢)、where或having後面(支援標量子查詢、列子查詢、行子查詢)、exists後面(相關子查詢、支援表子查詢)
- 按結果集的行列數不同 :標量子查詢(結果集只有一行一列)、列子查詢(結果集只有一列多行)、行子查詢(結果集有一行多列)、表子查詢(結果集一般為多行多列)
- where 或having後面
1.標量子查詢(單行子查詢)
2.列子查詢(多行子查詢)
3.行子查詢(多列多行)
特點:1.子查詢都或放在小括號內;2.子查詢一般放在條件的右側;3.標量子查詢,一般搭配著單行操作符使用 > < >= <= = <>
列子查詢,一般搭配著多行操作符使用 in、any/some、all
4、子查詢的執行優先於主查詢執行,主查詢的條件用到了子查詢的結果 - 標量子查詢
#案例1 :查詢誰的工資比abel高?
select *
from emoloyees
where salary>(
select salary
from employees
where last_name= 'abel'
);
#案例2:返回job_id與141號員工相同,salary比143號員工多的員工,姓名、job_id和工資
select last_name,salary
from employees
where job_id=(
select job_id
from employees
where employee_id=141
) and
salary>(
select salary
from employees
where employee_id = 143
);
#案例3:返回公司工資最少的員工 last_name
select last_name
from employees
where salary=(
select min(salary)
from employees
);
#案例4:查詢最低工資大於50號部門最低工資的部門id和其最低工資
select min(salary),department_id
from employees
group by department_id
having min(salary)>(
select min(salary)
from employees
where department_id =50
);
- 列子查詢(多行子查詢)
#案例1:返回location_id是1400或1700的部門中 所有員工姓名
select last_name
from employees
where department_id in(
select distinct department_id
from departments
where location_id in(1400,1700)
);
#案例2:返回其它工種中job_id 為‘IT_prog’工種任一工資都低的員工的員工號、姓名、工資
select last_name,employees_id,salary
from employees
where salary<any(
select salary
from employees
where job_id = 'IT_PROG') and
job_id<>'IT_PROG';
#案例3:返回其它部門中job_id 為‘IT_PROG’部門所有工資都低的員工的員工名、姓名以及salary
select last_name,salary
from employees
where salary<all(
select salary
from employees
where job_id = 'IT_PROG') and
job_id<>'IT_PROG';
- 行子查詢
#查詢員工編號最小並且工資最高的員工資訊
select *
from employees
where (employees_id,salary) = (
select min(employees_id),max(salary)
from employees
);
- select後面的子查詢
- from 後面的子查詢
將子查詢結果充當一張表,要求必須起別名
#案例:查詢每個部門的平均工資的工資等級
select ag_dep.*,g.'grade_level'
from (
select avg(salary) ag,department_id
from employees
group by department_id
) ag_dep
inner join job_grades g
on ag_dep.agbetween lowest_sal and highest_sal;
- exists後面(相關子查詢)
語法:exists(完整的查詢語句)
結果為1或0 - 練習
#1、查詢和zlotkey相同部門的員工姓名和工資
select last_name,salary
from employees
where department_id = (
select department_id
from employees
where last_name = 'zlotkey'
);
#2、查詢工資比公司平均工資高的員工的員工號、姓名和工資
select employees_id,salary
from employees
where salary>(
select avg(salary)
from employees
);
#3、查詢各部門中工資比本部門平均工資高的員工的員工號、姓名和工資
select employee_id,salary
from employees e
inner join (
select avg(salary) ag,department_id
from employees
group by department_id
) ag_dep
on e,department_id = ag_dep.department_id
where salary>ag_dep.ag;
#4、查詢姓名中包含字母u的員工在相同部門的員工的員工號和姓名
select employees_id,last_name
from employees
where department_id in(
select department_id
from employees
where last_name like %u%
);
#5、查詢在部門的location_id為1700的部門工作的員工的員工號
select employee_id
from employees
where department_id = any(
select department_id
from departments
where location_id = 1700
);
#6、查詢管理者是King的員工姓名和工資
select last_name,salary
from employees
where manager_id in(
select employee_id
from employees
where last_name = 'king'
#7、查詢工資最高的員工的姓名,要求要求first_name 和last_name顯示為一列,列名為姓.名
select concat(first_name,last_name) “姓.名”
from employees
where salary=(
select max(salary)
from employees
);
進階九:分頁查詢
- 應用場景:當要顯示的資料,一頁顯示不全,需要分頁提交sql請求
- 語法結構:select 查詢列表
from 表
【join type join 表2
on 連線條件
where 篩選條件
group by 分組欄位
having 分組後的篩選
order by 排序的欄位
】
limit【offset】 size
offset:要顯示條目的起始索引(起始索引從0開始)
size:要顯示的條目個數 - 特點:1、limit語句放在查詢語句的最後
2、公示:要顯示的頁數 page ,每頁的條目數 size
select 查詢列表
from 表
limit (page-1)*size,size
#案例1:查詢前五條員工資訊
select * from employees limit 0,5;
#案例2:查詢第11-25條的員工資訊
select * from employees limit 10,15;
#案例3:有獎金的員工資訊,並且工資較高的前十名顯示出來
select *
from employees
where commission_pct is not null
order by salary desc
limit 10;
- 截止目前,查詢語句中涉及的所有關鍵字,以及執行先後順序
select 查詢列表 7
from 表 1
連線型別 join 表2 2
on 連線條件 3
where 篩選條件 4
group by 分組欄位 5
having 分組後篩選 6
order by 排序 8
limit 起始索引,顯示條目數 9
- 練習
#1、查詢工資最低的員工資訊:last_name,salary
select last_name,salary
from employees
where salary=(
select min(salary)
from employees
);
#2、查詢平均工資最低的部門資訊
select *
from departments
where department_id = (
select department_id
from employees
group by department_id
order by avg(salary)
limit 1
);
#3、查詢平均工資最低的部門資訊和該部門的平均工資
select d.*,avg
from department d
join (
select avg(salary) avg,department_id
from employees
group by department_id
order by avg(salary)
limit 1
) ag_dep
on d.'department_id'=ag_dep.'department_id'
#4、查詢平均工資最高的job資訊
select *
from jobs
where job_id=(
select job_id
from employees
group by job_id
order by avg(salary) desc
limit 1
);
#5、查詢平均工資高於公司平均工資的部門有哪些
select avg(salary),department_id
from employees
group by department_id
having avg(salary)>(
select avg(salary)
from employees
);
#6、查詢出公司中所有manager的詳細資訊
select *
from employees
where employee_id = any(
select distinct manager_id
from employees
);
#7、各個部門中最高工資中最低的那個部門的最低工資是多少
select min(salary)
from employees
where department_id=(
select department_id
from employees
group by department_id
order by max(salary)
limit 1
);
#8、查詢平均工資最高的部門的manager的詳細資訊:
last_name,email,salary
from employees
inner join
departments d
on d.manager_id = e.employees_id
where d.department_id= (
select department_id
from employees
group by department_id
order by avg(salary) desc
limit 1
);
進階十:聯合查詢
- union 聯合 合併:將多條查詢語句的結果合併成一個結果
- 語法:
查詢語句1
union
查詢語句2
union
… - 應用場景:要查詢的結果來自多個表,且多個表沒有連線關係, 但查詢的資訊一致時
- 特點:1、要求多條查詢的查詢列數一致時
2、要求多條查詢語句的查詢的每一列的型別和順序最好一致
3、union關鍵字預設去重,如果使用union all可以包含重複項
三、DML語言
資料操作語言
- 插入:insert
- 修改:update
- 刪除:delete
插入語句
- 語法:insert into 表名(列名…)values(值1,…)
- 注意:1、插入的值得型別要與列的型別一致或相容
insert into beauty(id,name,sex,borndate,phone,photo,boyfriend_id)
values(13,'唐藝昕','女','1990-4-23','18912345667',null,12);
2、不可以為null的列必須插入值,可以為null的列如何插入值?
方式一:
insert into beauty(id,12)
方式二:
insert into beauty(id,12);
3、列的順序是否可以調換?
insert into brauty(name,id,sex) 可以調換列的順序
values('蔣欣',16,'183333333','女');
4、列數和值得個數必須一致
5、可以省略列名,預設所有列,而且列的順序和表中列的順序一致
insert into beauty
values(18,'張飛','男','119',null);
- 方式二
語法:insert into 表名 set 列名=值,列名=值,…
insert into beauty
set id=19,name='劉濤',phone='111';
- 兩種方式大pk
1、方式一支援插入多行,方式二不支援
insert into beauty(id,boyfriend_id)
values(23,'唐藝昕1',12),(24,'唐藝昕2',(25,'唐藝昕3',12);
2、方式一支援子查詢,方式二不支援
二、修改語句
1、修改單表的記錄
語法:
update 表名
set 列=新值,列=新值,…
where 篩選條件
#案例1:修改beauty表中姓唐的女神的電話為1388888
update beauty set iphone='1388888'
where name like '唐%';
#案例2:修改boys表中ID為2的名稱為張飛,魅力值為10
update boys set name='張飛',usercp=10
where id=2;
2、修改多表的記錄
語法:
update 表1 別名
inner|left|right join 表2 別名
on 連線條件
set 列=值,…
where 篩選條件;
#案例:修改張無忌的女朋友的電話為119
update boy bo
inner join beauty b
on b.'id'=bo.'boyfriendid'
set phone=119
where bo.'boyname'='張無忌';
三、刪除語句
方式一:delete
1、單表刪除
語法:delete from 表名 where 篩選條件;
#案例:刪除手機號一9結尾的女神資訊
delete from beauty where phone like '%9';
2、多表刪除
方式二:truncate
語法:truncate table 表名;
#案例1:刪除張無忌的女朋友的資訊
delete b
from beauty b
inner join boys bo
on b.'boyfriends_id'=bo.'id'
where bo.'boyname'='張無忌';
#案例2:刪除黃曉明的資訊和他女朋友的資訊
delete b,bo
from boys bo
inner join beauty b on b.'boyfriend_id'=bo.'id'
where bo.'boyname'='黃曉明';
四、DDL語言
資料定義語言
庫和表的管理
- 庫的管理
建立、修改、刪除 - 表的管理
建立、修改、刪除
建立:create
修改:alter
刪除:drop
庫的管理
- 庫的建立
語法:create database [if not exists] 庫名;
create database chen;
- 庫的修改
rename database books to 新庫名;
- 更改庫的字符集
alter database books character set gbk;
- 庫的刪除
drop database books;
表的管理
- 表的建立
create table 表名(
列名 列的型別 【(長度) 約束】,
列名 列的型別 【(長度) 約束】,
列名 列的型別 【(長度) 約束】,
列名 列的型別 【(長度) 約束】,
...
列名 列的型別 【(長度) 約束】
);
- 表的修改
1、修改列名
alter table book change column publishdate pubdate datetime;
2、修改列的型別或約束
alter table book modify column pubdate timestamp;
3、新增新列
alter table book add colunmn annual double;
4、刪除列
alter table book drop column annual;
5、修改表名
alter table book rename to chen_book;
- 表的刪除
drop table book;
show tables;#檢視當前庫的表
#通用的寫法
drop database if exists 舊庫名;
create database 新庫名;
drop table if exists 舊錶名;
create table 新表名();
- 表的複製
#僅僅複製表的結構
create table chen like book;
#複製表的結構+資料
create table chen1
select * from book;
#只複製部分資料
create table chen3
select id,name
from book
where country='china';
#僅僅複製某些欄位
create table chen4
select ID
from book
where 0;
#跨資料庫插入資料
create table chen5
select department_id,department_name
from myemployees.departments;
常見的資料型別
- 數值型
1、整形
tinyint、smallint、mediumint、int/integer、bigint
特點:
如果不設定無符號還是有符號,預設是有符號,如果想設定無符號,需要新增unsigned;
如果插入的數值超出了整形的範圍,會報out of range 異常,並且插入臨界值;
如果不設定長度,會有預設的長度
2、小數
分類:浮點型float、定點型double
2.1 定點數
2.2 浮點數 - 字元型
1、較短的文字 :char(m)代表固定長度字元、varchar(m)代表可變字元;m代表最多字元數
2、較長的文字:text、blob(較長的二進位制資料) - 日期型
分類:date 只儲存日期、time只儲存時間、year只儲存年、datetime儲存日期+時間、timestamp儲存日期+時間(受時區影響)
常見約束
- 含義: 一種限制,用於限制表中的資料,為了保證表中的資料的準確和可靠性
- 分類:六大約束
not null :非空,為了保證該欄位的值不能為空;
default:預設,用於保證該欄位有預設值;
primary key:主鍵,用於保證該欄位的值具有唯一性,並且非空;
unique:唯一,用於保證該欄位的值具有唯一性,可以為空;
check:檢查約束【mysql中不支援】;
foreign key:外來鍵,用於限制兩個表的關係的,用於保證該欄位值必須來自主表的關聯的值;在從表新增外來鍵約束,用於引用主表某列的值;
新增約束的時機:1、建立表時;2、修改表時
約束的新增分類:1、列級約束:六大約束語法上都支援,但外來鍵約束沒有效果;2、表級約束:除了非空,預設,其它都支援
- 建立表時新增約束
1、新增列級約束
語法:直接在欄位名和型別後面追加約束
use student;
create table stuinfo(
id int primary key,#主鍵
stuname varchar(20) not null,#非空
seat int default 18,#預設約束
gender char(1) check(gender='男' or gender='女')#檢查
age int unique,#唯一
majorID int references major(id)#外來鍵
#檢視book表中所有的索引,包括主鍵、外來鍵、唯一
show index from book;
2、新增表級約束
語法:在各個欄位的最下面
constraint 約束名 約束型別(欄位名)
drop table if exists book;
create table stuinfo(
id int,stuname varchar(20),gender char(1),seat int,age int,majorid int,constraint pk primary key(id);
- 通用的寫法
create table if not exists stuinfo(
id int primary key,stuname varchar(20) not null,sex char(1),age int default 18,seat int unique,constraint fk_stuinfo_major foreign key(majorid) references major(id)
);
外來鍵特點:1、要求在從表設定外來鍵關係;2、從表額外來鍵列的
- 修改表時新增約束
- 標識列
又稱為自增長列, 可以不用手動的插入值,系統提供預設的序列值。
一、建立表時設定標識列
create table tab_identify(
id int primary key auto_increment,name varchar(20)
);
五、TCL(transaction control language)事務控制語言
- 事務:一個或一組sql語句組成一個執行單元,這個執行單元要麼全部執行,要麼全部不執行。
- 事務的ACID屬性:
1、原子性:原子性是指事務是一個不可分割的工作單元,事務中的操作要麼都發生,要不都不發生;
2、一致性:事務必須使資料庫從一個一致性狀態變換到另一個一致性狀態;
3、隔離性:事務的隔離性是指一個事務的執行不能被其它事務所幹擾,即一個事務內部的操作及使用的資料對併發的其它 事務是隔離的,併發執行的各個事務之間不能互相干擾;
4、永續性:永續性是指一個事務一旦被提交,它對資料庫中資料的改變就是永久性的,接下來的其它操作和資料庫故障不應該對其有任何影響。 - 事務的建立
1、隱式事務:事務沒有明顯的開啟和結束的標記
比如insert 、update、delete語句
2、顯式事務:事務具有明顯的開啟和結束的標誌;
前提:必須先設定自動提交功能禁用。
#步驟1
set autocommit=0;
#步驟2:編寫事務中的sql語句(select,insert,update,delete)
語句1
語句2
#步驟3:結束事務
commit;提交事務
rollback;回滾事務
演示事務的使用步驟:
#開啟事務
set autocommit=0;
start transaction;
#編寫一組事務的語句
update account set balance = 500 where username='張無忌';
update account set balance = 1500 where username='趙敏';
#結束事務
commit;