MySQL基礎:基礎查詢

DQL語言:數據查詢語言

3.1 基礎查詢

語法java

select 查詢列表
from 表名;

特色mysql

查詢列表能夠是字段、常量、表達式、函數,也能夠是多個
查詢結果是一個虛擬表

示例sql

一、查詢單個字段
select 字段名 from 表名;

二、查詢多個字段
select 字段名,字段名 from 表名;

三、查詢全部字段
select * from 表名

四、查詢常量
select 常量值;
注意:字符型和日期型的常量值必須用單引號引發來,數值型不須要

五、查詢函數
select 函數名(實參列表);

六、查詢表達式
select 100/1234;

七、起別名
①as
②空格

八、去重
select distinct 字段名 from 表名;

九、+
做用:作加法運算
select 數值+數值; 直接運算
select 字符+數值;先試圖將字符轉換成數值,若是轉換成功,則繼續運算;不然轉換成0,再作運算
select null+值;結果都爲null

十、【補充】concat函數
功能:拼接字符
select concat(字符1,字符2,字符3,...);

十一、【補充】ifnull函數
功能:判斷某字段或表達式是否爲null,若是爲null 返回指定的值,不然返回本來的值
select ifnull(commission_pct,0) from employees;

十二、【補充】isnull函數
功能:判斷某字段或表達式是否爲null,若是是,則返回1,不然返回0

基礎查詢的示例:數據庫

#進階1:基礎查詢
/*
語法:
select 查詢列表 from 表名;


相似於:System.out.println(打印東西);

特色:

一、查詢列表能夠是:表中的字段、常量值、表達式、函數
二、查詢的結果是一個虛擬的表格
*/

USE myemployees;

#1.查詢表中的單個字段

SELECT last_name FROM employees;

#2.查詢表中的多個字段
SELECT last_name,salary,email FROM employees;

#3.查詢表中的全部字段

#方式一:
SELECT 
    `employee_id`,
    `first_name`,
    `last_name`,
    `phone_number`,
    `last_name`,
    `job_id`,
    `phone_number`,
    `job_id`,
    `salary`,
    `commission_pct`,
    `manager_id`,
    `department_id`,
    `hiredate` 
FROM
    employees ;
#方式二:  
 SELECT * FROM employees;
 
 #4.查詢常量值
 SELECT 100;
 SELECT 'john';
 
 #5.查詢表達式
 SELECT 100%98;
 
 #6.查詢函數
 
 SELECT VERSION();
 
 
 #7.起別名
 /*
 ①便於理解
 ②若是要查詢的字段有重名的狀況,使用別名能夠區分開來
 
 */
 #方式一:使用as
SELECT 100%98 AS 結果;
SELECT last_name AS 姓,first_name AS 名 FROM employees;

#方式二:使用空格
SELECT last_name 姓,first_name 名 FROM employees;


#案例:查詢salary,顯示結果爲 out put
SELECT salary AS "out put" FROM employees;


#8.去重


#案例:查詢員工表中涉及到的全部的部門編號
SELECT DISTINCT department_id FROM employees;


#9.+號的做用

/*

java中的+號:
①運算符,兩個操做數都爲數值型
②鏈接符,只要有一個操做數爲字符串

mysql中的+號:
僅僅只有一個功能:運算符

select 100+90; 兩個操做數都爲數值型,則作加法運算
select '123'+90;只要其中一方爲字符型,試圖將字符型數值轉換成數值型
			若是轉換成功,則繼續作加法運算
select 'john'+90;	若是轉換失敗,則將字符型數值轉換成0

select null+10; 只要其中一方爲null,則結果確定爲null

*/

#案例:查詢員工名和姓鏈接成一個字段,並顯示爲 姓名


SELECT CONCAT('a','b','c') AS 結果;

SELECT 
	CONCAT(last_name,first_name) AS 姓名
FROM
	employees;

3.2 條件查詢

語法安全

select 查詢列表
from 表名
where 篩選條件

篩選條件的分類服務器

一、簡單條件運算符
> < = <> != >= <=    <=>安全等於

二、邏輯運算符
 && and
  || or
  !  not
  
三、模糊查詢
 like:通常搭配通配符使用,能夠判斷字符型或數值型
 通配符:%任意多個字符,_任意單個字符

between and
in
is null /is not null:用於判斷null值

is null PK <=>
			普通類型的數值	null值		可讀性
is null		×			√		√
<=>		√			√		×

條件查詢的示例markdown

#進階2:條件查詢
/*

語法:
	select 
		查詢列表
	from
		表名
	where
		篩選條件;

分類:
	1、按條件表達式篩選
	
	簡單條件運算符:> < = != <> >= <=
	
	2、按邏輯表達式篩選
	邏輯運算符:
	做用:用於鏈接條件表達式
		&& || !
		and or not
		
	&&和and:兩個條件都爲true,結果爲true,反之爲false
	||或or: 只要有一個條件爲true,結果爲true,反之爲false
	!或not: 若是鏈接的條件自己爲false,結果爲true,反之爲false
	
	3、模糊查詢
		like
		between and
		in
		is null
	
*/
#1、按條件表達式篩選

#案例1:查詢工資>12000的員工信息

SELECT 
	*
FROM
	employees
WHERE
	salary>12000;
	
	
#案例2:查詢部門編號不等於90號的員工名和部門編號
SELECT 
	last_name,
	department_id
FROM
	employees
WHERE
	department_id<>90;


#2、按邏輯表達式篩選

#案例1:查詢工資z在10000到20000之間的員工名、工資以及獎金
SELECT
	last_name,
	salary,
	commission_pct
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;
#3、模糊查詢
/*
like

	
	
between and
in
is null|is not null

*/
#1.like
/*
特色:
①通常和通配符搭配使用
	通配符:
	% 任意多個字符,包含0個字符
	_ 任意單個字符
*、

#案例1:查詢員工名中包含字符a的員工信息

select 
	*
from
	employees
where
	last_name like '%a%';#abc
#案例2:查詢員工名中第三個字符爲e,第五個字符爲a的員工名和工資
select
	last_name,
	salary
FROM
	employees
WHERE
	last_name LIKE '__n_l%';



#案例3:查詢員工名中第二個字符爲_的員工名

SELECT
	last_name
FROM
	employees
WHERE
	last_name LIKE '_$_%' ESCAPE '$';
#2.between and
/*
①使用between and 能夠提升語句的簡潔度
②包含臨界值
③兩個臨界值不要調換順序

*/


#案例1:查詢員工編號在100到120之間的員工信息

SELECT
	*
FROM
	employees
WHERE
	employee_id >= 120 AND employee_id<=100;
#----------------------
SELECT
	*
FROM
	employees
WHERE
	employee_id BETWEEN 120 AND 100;

#3.in
/*
含義:判斷某字段的值是否屬於in列表中的某一項
特色:
	①使用in提升語句簡潔度
	②in列表的值類型必須一致或兼容
	③in列表中不支持通配符
	

*/
#案例:查詢員工的工種編號是 IT_PROG、AD_VP、AD_PRES中的一個員工名和工種編號

SELECT
	last_name,
	job_id
FROM
	employees
WHERE
	job_id = 'IT_PROT' OR job_id = 'AD_VP' OR JOB_ID ='AD_PRES';


#------------------

SELECT
	last_name,
	job_id
FROM
	employees
WHERE
	job_id IN( 'IT_PROT' ,'AD_VP','AD_PRES');

#四、is null
/*
=或<>不能用於判斷null值
is null或is not null 能夠判斷null值




*/

#案例1:查詢沒有獎金的員工名和獎金率
SELECT
	last_name,
	commission_pct
FROM
	employees
WHERE
	commission_pct IS NULL;


#案例1:查詢有獎金的員工名和獎金率
SELECT
	last_name,
	commission_pct
FROM
	employees
WHERE
	commission_pct IS NOT NULL;

#----------如下爲×
SELECT
	last_name,
	commission_pct
FROM
	employees

WHERE 
	salary IS 12000;
	
	
#安全等於  <=>


#案例1:查詢沒有獎金的員工名和獎金率
SELECT
	last_name,
	commission_pct
FROM
	employees
WHERE
	commission_pct <=>NULL;
	
	
#案例2:查詢工資爲12000的員工信息
SELECT
	last_name,
	salary
FROM
	employees

WHERE 
	salary <=> 12000;
	

#is null pk <=>

IS NULL:僅僅能夠判斷NULL值,可讀性較高,建議使用
<=>    :既能夠判斷NULL值,又能夠判斷普通的數值,可讀性較低

3.3 排序查詢

語法oracle

select 查詢列表
from 表
where 篩選條件
order by 排序列表 【asc}desc】

特色函數

asc :升序,若是不寫默認升序
   desc:降序

排序列表 支持 單個字段、多個字段、函數、表達式、別名

order by的位置通常放在查詢語句的最後(除limit語句以外)

3.4 常見函數

概述sqlserver

功能:相似於java中的方法
好處:提升重用性和隱藏實現細節
調用:select 函數名(實參列表);

單行函數

一、字符函數
  concat:鏈接
  substr:截取子串
  upper:變大寫
  lower:變小寫
  replace:替換
  length:獲取字節長度
  trim:去先後空格
  lpad:左填充
  rpad:右填充
  instr:獲取子串第一次出現的索引
  
二、數學函數
  ceil:向上取整
  round:四捨五入
  mod:取模
  floor:向下取整
  truncate:截斷
  rand:獲取隨機數,返回0-1之間的小數

三、日期函數
  now:返回當前日期+時間
  year:返回年
  month:返回月
  day:返回日
  date_format:將日期轉換成字符
  curdate:返回當前日期
  str_to_date:將字符轉換成日期
  curtime:返回當前時間
  hour:小時
  minute:分鐘
  second:秒
  datediff:返回兩個日期相差的天數
  monthname:以英文形式返回月


四、其餘函數
  version 當前數據庫服務器的版本
  database 當前打開的數據庫
  user當前用戶
  password('字符'):返回該字符的密碼形式
  md5('字符'):返回該字符的md5加密形式


五、流程控制函數
  ①if(條件表達式,表達式1,表達式2):若是條件表達式成立,返回表達式1,不然返回表達式2
  ②case狀況1
  case 變量或表達式或字段
  when 常量1 then 值1
  when 常量2 then 值2
  ...
  else 值n
  end
  ③case狀況2
  case 
  when 條件1 then 值1
  when 條件2 then 值2
  ...
  else 值n
  end

單行函數的示例:

#進階4:常見函數

/*

概念:相似於java的方法,將一組邏輯語句封裝在方法體中,對外暴露方法名
好處:一、隱藏了實現細節  二、提升代碼的重用性
調用:select 函數名(實參列表) 【from 表】;
特色:
	①叫什麼(函數名)
	②幹什麼(函數功能)

分類:
	一、單行函數
	如 concat、length、ifnull等
	二、分組函數
	
	功能:作統計使用,又稱爲統計函數、聚合函數、組函數
	
常見函數:
	1、單行函數
	字符函數:【mysql中字符下標從1開始】
	length:獲取字節個數(utf-8一個漢字表明3個字節,gbk爲2個字節)
	concat:字段、字符鏈接
	substr:字符串截取,三個參數(截什麼,從哪裏開始,截幾個)
	instr :返回子串第一次出現的索引,若是找不到返回0
	trim : 去首尾空格,也可去除自定字符
	upper :轉大寫
	lower :轉小寫
	lpad  :用指定的字符實現左填充指定長度
	rpad  :用指定的字符實現右填充指定長度
	replace:替換,三個參數(須要替換的字符串,原字符串,目標字符串)
	
	數學函數:
	round:四捨五入
	ceil:向上取整,返回>=該參數的最小整數
	floor:向下取整,返回<=該參數的最大整數
	truncate:截取小數後幾位
	mod :取餘
	
	日期函數:
	now:返回當前系統日期+時間
	curdate:返回當前系統日期,不包含時間
	curtime:返回當前時間,不包含日期
	year
	month
	monthname
	day
	hour
	minute
	second
	str_to_date:將字符經過指定的格式轉換成日期
	date_format:將日期轉換成字符
	
	其餘函數:
	version :查看mysql版本號
	database :查看數據庫
	user	:查看當前用戶
	控制函數
	if: 三個參數,相似三元表達式
	case:多種狀況,相似switch case

*/


#1、字符函數

#1.length 獲取參數值的字節個數
SELECT LENGTH('john');
SELECT LENGTH('張三丰hahaha');

SHOW VARIABLES LIKE '%char%'

#2.concat 拼接字符串

SELECT CONCAT(last_name,'_',first_name) 姓名 FROM employees;

#3.upper、lower
SELECT UPPER('john');
SELECT LOWER('joHn');
#示例:將姓變大寫,名變小寫,而後拼接
SELECT CONCAT(UPPER(last_name),LOWER(first_name))  姓名 FROM employees;

#4.substr、substring
注意:索引從1開始
#截取從指定索引處後面全部字符
SELECT SUBSTR('李莫愁愛上了陸展元',7)  out_put;

#截取從指定索引處指定字符長度的字符
SELECT SUBSTR('李莫愁愛上了陸展元',1,3) out_put;


#案例:姓名中首字符大寫,其餘字符小寫而後用_拼接,顯示出來

SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),'_',LOWER(SUBSTR(last_name,2)))  out_put
FROM employees;

#5.instr 返回子串第一次出現的索引,若是找不到返回0

SELECT INSTR('楊不殷六俠悔愛上了殷六俠','殷八俠') AS out_put;

#6.trim

SELECT LENGTH(TRIM('    張翠山    ')) AS out_put;

SELECT TRIM('aa' FROM 'aaaaaaaaa張aaaaaaaaaaaa翠山aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')  AS out_put;

#7.lpad 用指定的字符實現左填充指定長度

SELECT LPAD('殷素素',2,'*') AS out_put;

#8.rpad 用指定的字符實現右填充指定長度

SELECT RPAD('殷素素',12,'ab') AS out_put;


#9.replace 替換

SELECT REPLACE('周芷若周芷若周芷若周芷若張無忌愛上了周芷若','周芷若','趙敏') AS out_put;



#2、數學函數

#round 四捨五入
SELECT ROUND(-1.55);
SELECT ROUND(1.567,2);


#ceil 向上取整,返回>=該參數的最小整數

SELECT CEIL(-1.02);

#floor 向下取整,返回<=該參數的最大整數
SELECT FLOOR(-9.99);

#truncate 截斷

SELECT TRUNCATE(1.69999,1);

#mod取餘
/*
mod(a,b) :  a-a/b*b

mod(-10,-3):-10- (-10)/(-3)*(-3)=-1
*/
SELECT MOD(10,-3);
SELECT 10%3;


#3、日期函數

#now 返回當前系統日期+時間
SELECT NOW();

#curdate 返回當前系統日期,不包含時間
SELECT CURDATE();

#curtime 返回當前時間,不包含日期
SELECT CURTIME();


#能夠獲取指定的部分,年、月、日、小時、分鐘、秒
SELECT YEAR(NOW()) 年;
SELECT YEAR('1998-1-1') 年;

SELECT  YEAR(hiredate) 年 FROM employees;

SELECT MONTH(NOW()) 月;
SELECT MONTHNAME(NOW()) 月;


#str_to_date 將字符經過指定的格式轉換成日期

SELECT STR_TO_DATE('1998-3-2','%Y-%c-%d') AS out_put;

#查詢入職日期爲1992--4-3的員工信息
SELECT * FROM employees WHERE hiredate = '1992-4-3';

SELECT * FROM employees WHERE hiredate = STR_TO_DATE('4-3 1992','%c-%d %Y');


#date_format 將日期轉換成字符

SELECT DATE_FORMAT(NOW(),'%y年%m月%d日') AS out_put;

#查詢有獎金的員工名和入職日期(xx月/xx日 xx年)
SELECT last_name,DATE_FORMAT(hiredate,'%m月/%d日 %y年') 入職日期
FROM employees
WHERE commission_pct IS NOT NULL;


#4、其餘函數

SELECT VERSION();
SELECT DATABASE();
SELECT USER();


#5、流程控制函數
#1.if函數: if else 的效果

SELECT IF(10<5,'大','小');

SELECT last_name,commission_pct,IF(commission_pct IS NULL,'沒獎金,呵呵','有獎金,嘻嘻') 備註
FROM employees;




#2.case函數的使用一: switch case 的效果

/*
java中
switch(變量或表達式){
	case 常量1:語句1;break;
	...
	default:語句n;break;


}

mysql中

case 要判斷的字段或表達式
when 常量1 then 要顯示的值1或語句1;
when 常量2 then 要顯示的值2或語句2;
...
else 要顯示的值n或語句n;
end
*/

/*案例:查詢員工的工資,要求

部門號=30,顯示的工資爲1.1倍
部門號=40,顯示的工資爲1.2倍
部門號=50,顯示的工資爲1.3倍
其餘部門,顯示的工資爲原工資

*/


SELECT salary 原始工資,department_id,
CASE department_id
WHEN 30 THEN salary*1.1
WHEN 40 THEN salary*1.2
WHEN 50 THEN salary*1.3
ELSE salary
END AS 新工資
FROM employees;



#3.case 函數的使用二:相似於 多重if
/*
java中:
if(條件1){
	語句1;
}else if(條件2){
	語句2;
}
...
else{
	語句n;
}

mysql中:

case 
when 條件1 then 要顯示的值1或語句1
when 條件2 then 要顯示的值2或語句2
。。。
else 要顯示的值n或語句n
end
*/

#案例:查詢員工的工資的狀況
若是工資>20000,顯示A級別
若是工資>15000,顯示B級別
若是工資>10000,顯示C級別
不然,顯示D級別


SELECT salary,
CASE 
WHEN salary>20000 THEN 'A'
WHEN salary>15000 THEN 'B'
WHEN salary>10000 THEN 'C'
ELSE 'D'
END AS 工資級別
FROM employees;

分組函數

一、分類
 max 最大值
 min 最小值
 sum 和
 avg 平均值
 count 計算個數

 二、特色

 ①語法
 select max(字段) from 表名;

 ②支持的類型
 sum和avg通常用於處理數值型
 max、min、count能夠處理任何數據類型

 ③以上分組函數都忽略null
 ④均可以搭配distinct使用,實現去重的統計
 select sum(distinct 字段) from 表;
 ⑤count函數
 count(字段):統計該字段非空值的個數
 count(*):統計結果集的行數
 案例:查詢每一個部門的員工個數
 1 xx    10
 2 dd    20
 3 mm    20
 4 aa    40
 5 hh    40

 count(1):統計結果集的行數

 效率上:
 MyISAM存儲引擎,count(*)最高
 InnoDB存儲引擎,count(*)和count(1)效率>count(字段)

 ⑥ 和分組函數一同查詢的字段,要求是group by後出現的字段

分組函數實例

#2、分組函數
/*
功能:用做統計使用,又稱爲聚合函數或統計函數或組函數

分類:
sum 求和、avg 平均值、max 最大值 、min 最小值 、count 計算個數(非空)

特色:
一、sum、avg通常用於處理數值型
   max、min、count能夠處理任何類型
二、以上分組函數都忽略null值

三、能夠和distinct搭配實現去重的運算

四、count函數的單獨介紹
通常使用count(*)用做統計行數

五、和分組函數一同查詢的字段要求是group by後的字段

*/


#一、簡單 的使用
SELECT SUM(salary) FROM employees;
SELECT AVG(salary) FROM employees;
SELECT MIN(salary) FROM employees;
SELECT MAX(salary) FROM employees;
SELECT COUNT(salary) FROM employees;


SELECT SUM(salary) 和,AVG(salary) 平均,MAX(salary) 最高,MIN(salary) 最低,COUNT(salary) 個數
FROM employees;

SELECT SUM(salary) 和,ROUND(AVG(salary),2) 平均,MAX(salary) 最高,MIN(salary) 最低,COUNT(salary) 個數
FROM employees;

#二、參數支持哪些類型

SELECT SUM(last_name) ,AVG(last_name) FROM employees; #沒有意義
SELECT SUM(hiredate) ,AVG(hiredate) FROM employees;#可排序便可求和

SELECT MAX(last_name),MIN(last_name) FROM employees;

SELECT MAX(hiredate),MIN(hiredate) FROM employees;

SELECT COUNT(commission_pct) FROM employees;
SELECT COUNT(last_name) FROM employees;

#三、SUM、AVG等會忽略null,由於執行結果沒有null,null+任何值都爲null

SELECT SUM(commission_pct) ,AVG(commission_pct),SUM(commission_pct)/35,SUM(commission_pct)/107 FROM employees;

SELECT MAX(commission_pct) ,MIN(commission_pct) FROM employees;

SELECT COUNT(commission_pct) FROM employees;
SELECT commission_pct FROM employees;


#四、和distinct搭配

SELECT SUM(DISTINCT salary),SUM(salary) FROM employees;

SELECT COUNT(DISTINCT salary),COUNT(salary) FROM employees;



#五、count函數的詳細介紹

SELECT COUNT(salary) FROM employees;

SELECT COUNT(*) FROM employees;

SELECT COUNT(1) FROM employees;

效率:
MYISAM存儲引擎下  ,COUNT(*)的效率高
INNODB存儲引擎下,COUNT(*)和COUNT(1)的效率差很少,比COUNT(字段)要高一些


#六、和分組函數一同查詢的字段有限制

SELECT AVG(salary),employee_id  FROM employees;

3.5 分組查詢

語法

select 分組函數,分組後的字段
from 表
【where 篩選條件】
group by 分組的字段
【having 分組後的篩選】
【order by 排序列表】

特色

使用關鍵字		篩選的表	位置
		分組前篩選		where		原始表			group by的前面
  		分組後篩選		having		分組後的結果	  group by 的後面

分組函數示例

#2、分組函數
/*
功能:用做統計使用,又稱爲聚合函數或統計函數或組函數

分類:
sum 求和、avg 平均值、max 最大值 、min 最小值 、count 計算個數(非空)

特色:
一、sum、avg通常用於處理數值型
   max、min、count能夠處理任何類型
二、以上分組函數都忽略null值

三、能夠和distinct搭配實現去重的運算

四、count函數的單獨介紹
通常使用count(*)用做統計行數

五、和分組函數一同查詢的字段要求是group by後的字段

*/


#一、簡單 的使用
SELECT SUM(salary) FROM employees;
SELECT AVG(salary) FROM employees;
SELECT MIN(salary) FROM employees;
SELECT MAX(salary) FROM employees;
SELECT COUNT(salary) FROM employees;


SELECT SUM(salary) 和,AVG(salary) 平均,MAX(salary) 最高,MIN(salary) 最低,COUNT(salary) 個數
FROM employees;

SELECT SUM(salary) 和,ROUND(AVG(salary),2) 平均,MAX(salary) 最高,MIN(salary) 最低,COUNT(salary) 個數
FROM employees;

#二、參數支持哪些類型

SELECT SUM(last_name) ,AVG(last_name) FROM employees; #沒有意義
SELECT SUM(hiredate) ,AVG(hiredate) FROM employees;#可排序便可求和

SELECT MAX(last_name),MIN(last_name) FROM employees;

SELECT MAX(hiredate),MIN(hiredate) FROM employees;

SELECT COUNT(commission_pct) FROM employees;
SELECT COUNT(last_name) FROM employees;

#三、SUM、AVG等會忽略null,由於執行結果沒有null,null+任何值都爲null

SELECT SUM(commission_pct) ,AVG(commission_pct),SUM(commission_pct)/35,SUM(commission_pct)/107 FROM employees;

SELECT MAX(commission_pct) ,MIN(commission_pct) FROM employees;

SELECT COUNT(commission_pct) FROM employees;
SELECT commission_pct FROM employees;


#四、和distinct搭配

SELECT SUM(DISTINCT salary),SUM(salary) FROM employees;

SELECT COUNT(DISTINCT salary),COUNT(salary) FROM employees;



#五、count函數的詳細介紹

SELECT COUNT(salary) FROM employees;

SELECT COUNT(*) FROM employees;

SELECT COUNT(1) FROM employees;

效率:
MYISAM存儲引擎下  ,COUNT(*)的效率高
INNODB存儲引擎下,COUNT(*)和COUNT(1)的效率差很少,比COUNT(字段)要高一些


#六、和分組函數一同查詢的字段有限制

SELECT AVG(salary),employee_id  FROM employees;

分組查詢示例

#進階5:分組查詢,當條件在另外一個表中就須要分組查詢group by

/*
語法:

select 查詢列表
from 表
【where 篩選條件】
group by 分組的字段
【order by 排序的字段】;

特色:
一、和分組函數一同查詢的字段必須是group by後出現的字段
二、篩選分爲兩類:分組前篩選和分組後篩選
		
			針對的表				位置			  鏈接的關鍵字
分組前篩選	原始表					group by前		  where
	
分組後篩選	group by後的結果集      group by後		having

問題1:分組函數作篩選能不能放在where後面
答:不能

問題2:where——group by——having

通常來說,能用分組前篩選的,儘可能使用分組前篩選,提升效率

三、分組能夠按單個字段也能夠按多個字段
四、能夠搭配着排序使用




*/



#引入:查詢每一個部門的員工個數

SELECT COUNT(*) FROM employees WHERE department_id=90;
#1.簡單的分組

#案例1:查詢每一個工種的員工平均工資
SELECT AVG(salary),job_id
FROM employees
GROUP BY job_id;

#案例2:查詢每一個位置的部門個數

SELECT COUNT(*),location_id
FROM departments
GROUP BY location_id;


#二、能夠實現分組前的篩選

#案例1:查詢郵箱中包含a字符的 每一個部門的最高工資

SELECT MAX(salary),department_id
FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id;


#案例2:查詢有獎金的每一個領導手下員工的平均工資

SELECT AVG(salary),manager_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id;



#三、分組後篩選

#案例:查詢哪一個部門的員工個數>5

#①查詢每一個部門的員工個數
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id;

#② 篩選剛纔①結果

SELECT COUNT(*),department_id
FROM employees

GROUP BY department_id

HAVING COUNT(*)>5;


#案例2:每一個工種有獎金的員工的最高工資>12000的工種編號和最高工資

SELECT job_id,MAX(salary)
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX(salary)>12000;


#案例3:領導編號>102的每一個領導手下的最低工資大於5000的領導編號和最低工資

manager_id>102

SELECT manager_id,MIN(salary)
FROM employees
GROUP BY manager_id
HAVING MIN(salary)>5000;


#4.添加排序

#案例:每一個工種有獎金的員工的最高工資>6000的工種編號和最高工資,按最高工資升序

SELECT job_id,MAX(salary) m
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING m>6000
ORDER BY m ;

#5.按多個字段分組

#案例:查詢每一個工種每一個部門的最低工資,並按最低工資降序

SELECT MIN(salary),job_id,department_id
FROM employees
GROUP BY department_id,job_id
ORDER BY MIN(salary) DESC;

3.6 鏈接查詢

含義

當查詢中涉及到了多個表的字段,須要使用多表鏈接
select 字段1,字段2
from 表1,表2,...;

笛卡爾乘積:當查詢多個表時,沒有添加有效的鏈接條件,致使多個表全部行實現徹底鏈接
如何解決:添加有效的鏈接條件

分類

按年代分類:
  	sql92:至關於只有sql99的內鏈接部分
  		等值
  		非等值
  		自鏈接
	也支持一部分外鏈接(用於oracle、sqlserver,mysql不支持)
	
	sql99【推薦使用】
        內鏈接
            等值
            非等值
            自鏈接
        外鏈接
            左外
            右外
            全外(mysql不支持)
        交叉鏈接

SQL 92語法

一、等值鏈接
  語法:
  	select 查詢列表
  	from 表1 別名,表2 別名
  	where 表1.key=表2.key
  	【and 篩選條件】
  	【group by 分組字段】
  	【having 分組後的篩選】
  	【order by 排序字段】

  特色:
  	① 通常爲表起別名
  	②多表的順序能夠調換
  	③n錶鏈接至少須要n-1個鏈接條件
  	④等值鏈接的結果是多表的交集部分


  二、非等值鏈接
  語法:
  	select 查詢列表
  	from 表1 別名,表2 別名
  	where 非等值的鏈接條件
  	【and 篩選條件】
  	【group by 分組字段】
  	【having 分組後的篩選】
  	【order by 排序字段】
  	
  三、自鏈接【同一個表拆分紅多個表】
  語法:
  	select 查詢列表
  	from 表 別名1,表 別名2
  	where 等值的鏈接條件
  	【and 篩選條件】
  	【group by 分組字段】
  	【having 分組後的篩選】
  	【order by 排序字段】

SQL 99語法

一、內鏈接
  語法:
  select 查詢列表
  from 表1 別名
  【inner】 join 表2 別名 on 鏈接條件
  where 篩選條件
  group by 分組列表
  having 分組後的篩選
  order by 排序列表
  limit 子句;

  特色:
  ①表的順序能夠調換
  ②內鏈接的結果=多表的交集
  ③n錶鏈接至少須要n-1個鏈接條件

  分類:
  等值鏈接
  非等值鏈接
  自鏈接

  二、外鏈接
  語法:
  select 查詢列表
  from 表1 別名
  left|right|full【outer】 join 表2 別名 on 鏈接條件
  where 篩選條件
  group by 分組列表
  having 分組後的篩選
  order by 排序列表
  limit 子句;
  特色:
  ①查詢的結果=主表中全部的行,若是從表和它匹配的將顯示匹配行,若是從表沒有匹配的則顯示null
  ②left join 左邊的就是主表,right join 右邊的就是主表
    full join 兩邊都是主表
  ③通常用於查詢除了交集部分的剩餘的不匹配的行

  三、交叉鏈接

  語法:
  select 查詢列表
  from 表1 別名
  cross join 表2 別名;

  特色:
  相似於笛卡爾乘積

sql92語法鏈接查詢示例:(不推薦)

#進階6:鏈接查詢
/*
含義:又稱多表查詢,當查詢的字段來自於多個表時,就會用到鏈接查詢

笛卡爾乘積現象:表1 有m行,表2有n行,結果=m*n行

發生緣由:沒有有效的鏈接條件
如何避免:添加有效的鏈接條件

分類:

	按年代分類:
	sql92標準:僅僅支持內鏈接
	sql99標準【推薦】:支持內鏈接+外鏈接(左外和右外)+交叉鏈接
	
	按功能分類:
		內鏈接:
			等值鏈接
			非等值鏈接
			自鏈接
		外鏈接:
			左外鏈接
			右外鏈接
			全外鏈接
		
		交叉鏈接


*/

SELECT * FROM beauty;

SELECT * FROM boys;


SELECT NAME,boyName FROM boys,beauty
WHERE beauty.boyfriend_id= boys.id;

#1、sql92標準
#一、等值鏈接
/*

① 多表等值鏈接的結果爲多表的交集部分
②n錶鏈接,至少須要n-1個鏈接條件
③ 多表的順序沒有要求
④通常須要爲表起別名
⑤能夠搭配前面介紹的全部子句使用,好比排序、分組、篩選


*/



#案例1:查詢女神名和對應的男神名
SELECT NAME,boyName 
FROM boys,beauty
WHERE beauty.boyfriend_id= boys.id;

#案例2:查詢員工名和對應的部門名

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 e.last_name,e.job_id,j.job_title
FROM jobs j,employees e
WHERE e.`job_id`=j.`job_id`;


#四、能夠加篩選


#案例:查詢有獎金的員工名、部門名

SELECT last_name,department_name,commission_pct

FROM employees e,departments d
WHERE e.`department_id`=d.`department_id`
AND e.`commission_pct` IS NOT NULL;

#案例2:查詢城市名中第二個字符爲o的部門名和城市名

SELECT department_name,city
FROM departments d,locations l
WHERE d.`location_id` = l.`location_id`
AND city LIKE '_o%';

#五、能夠加分組


#案例1:查詢每一個城市的部門個數

SELECT COUNT(*) 個數,city
FROM departments d,locations l
WHERE d.`location_id`=l.`location_id`
GROUP BY city;


#案例2:查詢有獎金的每一個部門的部門名和部門的領導編號和該部門的最低工資
SELECT department_name,d.`manager_id`,MIN(salary)
FROM departments 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,departments d,locations l
WHERE e.`department_id`=d.`department_id`
AND d.`location_id`=l.`location_id`
AND city LIKE 's%'

ORDER BY department_name DESC;



#二、非等值鏈接


#案例1:查詢員工的工資和工資級別


SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.`lowest_sal` AND g.`highest_sal`
AND g.`grade_level`='A';

/*
select salary,employee_id from employees;
select * from job_grades;
CREATE TABLE job_grades
(grade_level VARCHAR(3),
 lowest_sal  int,
 highest_sal int);

INSERT INTO job_grades
VALUES ('A', 1000, 2999);

INSERT INTO job_grades
VALUES ('B', 3000, 5999);

INSERT INTO job_grades
VALUES('C', 6000, 9999);

INSERT INTO job_grades
VALUES('D', 10000, 14999);

INSERT INTO job_grades
VALUES('E', 15000, 24999);

INSERT INTO job_grades
VALUES('F', 25000, 40000);

*/


#三、自鏈接

#案例:查詢 員工名和上級的名稱

SELECT e.employee_id,e.last_name,m.employee_id,m.last_name
FROM employees e,employees m
WHERE e.`manager_id`=m.`employee_id`;

sql99語法鏈接查詢示例:(推薦)

#2、sql99語法
/*
語法:
	select 查詢列表
	from 表1 別名 【鏈接類型】
	join 表2 別名 
	on 鏈接條件
	【where 篩選條件】
	【group by 分組】
	【having 篩選條件】
	【order by 排序列表】
	

分類:
內鏈接(★):inner
外鏈接
	左外(★):left 【outer】
	右外(★):right 【outer】
	全外:full【outer】
交叉鏈接:cross 

*/


#一)內鏈接
/*
語法:

select 查詢列表
from 表1 別名
inner join 表2 別名
on 鏈接條件;

分類:
等值
非等值
自鏈接

特色:
①添加排序、分組、篩選
②inner能夠省略
③ 篩選條件放在where後面,鏈接條件放在on後面,提升分離性,便於閱讀
④inner join鏈接和sql92語法中的等值鏈接效果是同樣的,都是查詢多表的交集



*/


#一、等值鏈接
#案例1.查詢員工名、部門名

SELECT last_name,department_name
FROM departments d
 JOIN  employees e
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 departments d
ON e.`department_id`=d.`department_id`
GROUP BY department_name

#② 在①結果上篩選員工個數>3的記錄,並排序

SELECT COUNT(*) 個數,department_name
FROM employees e
INNER JOIN departments d
ON e.`department_id`=d.`department_id`
GROUP BY department_name
HAVING COUNT(*)>3
ORDER BY COUNT(*) DESC;

#5.查詢員工名、部門名、工種名,並按部門名降序(添加三表鏈接)

SELECT last_name,department_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;

#二)非等值鏈接

#查詢員工的工資級別

SELECT salary,grade_level
FROM employees e
 JOIN job_grades g
 ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_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 e.last_name,m.last_name
 FROM employees e
 JOIN employees m
 ON e.`manager_id`= m.`employee_id`;
 
  #查詢姓名中包含字符k的員工的名字、上級的名字
 SELECT e.last_name,m.last_name
 FROM employees e
 JOIN employees m
 ON e.`manager_id`= m.`employee_id`
 WHERE e.`last_name` LIKE '%k%';
 
 
 #2、外鏈接
 
 /*
 應用場景:用於查詢一個表中有,另外一個表沒有的記錄
 
 特色:
 一、外鏈接的查詢結果爲主表中的全部記錄
	若是從表中有和它匹配的,則顯示匹配的值
	若是從表中沒有和它匹配的,則顯示null
	外鏈接查詢結果=內鏈接結果+主表中有而從表沒有的記錄
 二、左外鏈接,left join左邊的是主表
    右外鏈接,right join右邊的是主表
 三、左外和右外交換兩個表的順序,能夠實現一樣的效果 
 四、全外鏈接=內鏈接的結果+表1中有但表2沒有的+表2中有但表1沒有的
 */
 
 #引入:查詢男友 不在男神表的的女神名
 
 SELECT * FROM beauty;
 SELECT * FROM boys;
 
 #左外鏈接
 SELECT b.*,bo.*
 FROM boys bo
 LEFT OUTER JOIN beauty b
 ON b.`boyfriend_id` = bo.`id`
 WHERE b.`id` IS NULL;
 
 
 #案例1:查詢哪一個部門沒有員工
 #左外
 SELECT d.*,e.employee_id
 FROM departments d
 LEFT OUTER JOIN employees e
 ON d.`department_id` = e.`department_id`
 WHERE e.`employee_id` IS NULL;
 
 
 #右外
 
 SELECT d.*,e.employee_id
 FROM employees e
 RIGHT OUTER JOIN departments d
 ON d.`department_id` = e.`department_id`
 WHERE e.`employee_id` IS NULL;
 
 
 #全外
  
 USE girls;
 SELECT b.*,bo.*
 FROM beauty b
 FULL OUTER JOIN boys bo
 ON b.`boyfriend_id` = bo.id;
 

 #交叉鏈接
 
 SELECT b.*,bo.*
 FROM beauty b
 CROSS JOIN boys bo;
 
 
 
 #sql92和 sql99pk
 /*
 功能:sql99支持的較多
 可讀性:sql99實現鏈接條件和篩選條件的分離,可讀性較高
 */

3.7 子查詢

含義

嵌套在其餘語句內部的select語句稱爲子查詢或內查詢,
外面的語句能夠是insert、update、delete、select等,通常select做爲外面語句較多
外面若是爲select語句,則此語句稱爲外查詢或主查詢

分類

一、按出現位置
select後面:
		僅僅支持標量子查詢
from後面:
		表子查詢
where或having後面:
		標量子查詢
		列子查詢
		行子查詢
exists後面:
		標量子查詢
		列子查詢
		行子查詢
		表子查詢

二、按結果集的行列
標量子查詢(單行子查詢):結果集爲一行一列
列子查詢(多行子查詢):結果集爲多行一列
行子查詢:結果集爲多行多列
表子查詢:結果集爲多行多列

示例

where或having後面
  一、標量子查詢
  案例:查詢最低工資的員工姓名和工資
  ①最低工資
  select min(salary) from employees

  ②查詢員工的姓名和工資,要求工資=①
  select last_name,salary
  from employees
  where salary=(
  	select min(salary) from employees
  );

  二、列子查詢
  案例:查詢全部是領導的員工姓名
  ①查詢全部員工的 manager_id
  select manager_id
  from employees

  ②查詢姓名,employee_id屬於①列表的一個
  select last_name
  from employees
  where employee_id in(
  	select manager_id
  	from employees
  );

3.8 分頁查詢

應用場景

當要查詢的條目數太多,一頁顯示不全

語法

select 查詢列表
from 表
limit 【offset,】size;
注意:
offset表明的是起始的條目索引,默認從0卡死
size表明的是顯示的條目數

公式:
假如要顯示的頁數爲page,每一頁條目數爲size
select 查詢列表
from 表
limit (page-1)*size,size;

3.9 聯合查詢

含義

union:合併、聯合,將屢次查詢結果合併成一個結果
2、語法
查詢語句1
union 【all】
查詢語句2
union 【all】
...

意義

將一條比較複雜的查詢語句拆分紅多條語句
適用於查詢多個表的時候,查詢的列基本是一致

特色

要求多條查詢語句的查詢列數必須一致
要求多條查詢語句的查詢的各列類型、順序最好一致
union 去重,union all包含重複項

3.10 查詢總結

語法:

​ select 查詢列表 ⑦ ​ from 表1 別名 ① ​ 鏈接類型 join 表2 ② ​ on 鏈接條件 ③ ​ where 篩選 ④ ​ group by 分組列表 ⑤ ​ having 篩選 ⑥ ​ order by排序列表 ⑧ ​ limit 起始條目索引,條目數; ⑨

相關文章
相關標籤/搜索