第35次文章:數據庫簡單查詢
- 2019 年 10 月 8 日
- 筆記
本周學習的數據庫,有一種明顯的感覺,語法簡單,基本上不會有大段大段的代碼出現,簡簡單單的幾行代碼就可以完成我們需要實現的任務,或許是因為我們的任務比較初級吧!嘻嘻!
所以本周主要分享的是一些語法結構,如果每個語法都給出一個例子的話,這篇文章將會出奇的長。所以,小白對於比較生疏的一些語法,會給出一個具體案例進行講解,剩餘比較簡單的案例,各位小夥伴就自己摸索一下,很簡單的喲!
遇到什麼問題,想要和小白討論的話,可以在文章下面留言,或者直接添加微信號:javaxiaobaizhushou,與小白面對面交流呀!下面進入正式的分享啦!
緊接上周的內容,補充一下常見的幾款數據庫管理系統:
mysql、oracle(甲骨文),db2(IBM)、sqlserver(微軟)
sql 語言分類
DQL語言的學習:數據查詢語言(date query language)
DML語言的學習:數據操作語言(data manipulation )
DDL語言:數據定義語言data define language
TCL語言:事務控制語言transaction control language
在下面使用到的案例中,我們都用下面的一張emp表進行查詢,所以我就先把這張表截圖放在這裡,便於後續的查看

tips:這張表格僅僅是用作我們在後續的操作,並沒有任何實際意義哈,不用糾結裏面的每個值是不是符合現實邏輯。
進階1:基礎查詢
一、語法
select 查詢列表 from 表名;
二、特點
1、查詢列表可以是字段、常量、表達式、函數,也可以是多個
2、查詢結果是一個虛擬表
三、示例
1、查詢單個字段
select 字段名 from 表名;
2、查詢多個字段
select 字段名,字段名 from 表名;
3、查詢所有的字段
select * from 表名;
4、查詢常量值
select 常量值;
注意:字符型和日期型的常量值必須用單引號引起來,數值型不需要
5、查詢函數
select 函數名(實參列表);
6、查詢表達式
select 100/1234;
注意:可以使用正常的加減乘除,但是不能使用java中++ —
7、起別名
(1)as
(2)空格
8、去重
select distinct 字段名 from 表名;
注意:去重的時候,只能對一個字段名進行去重處理。
9、+
作用:做加法運算
select 數值+數值;直接運算
select 字符+數值;先試圖將字符轉換成數值,如果轉換成功,則繼續運算;否則將字符轉換為0,再做運算。
select null+值;結果都為null
在這裡我們給出一個字符串連接的案例,便於各位同學的理解吧~
/* java中的+號: (1)運算符,兩個操作數都為數值型 (2)連接符,只要有一個操作數為字符型 mysql中的+號: 僅僅只有一個功能:運算符 select 100+90;兩個操作數都為數值型,則做加法運算 SELECT '123'+90; 只要其中一方為字符型,試圖將字符型數值轉換為數值型 如果轉化成功,則繼續做加法運算 SELECT 'ans'+90; 如果轉換失敗,則將字符型數值轉換為0 SELECT null+10; 只要其中一方為null,則其結果肯定為null */ #案例,查詢員工名和姓連接成一個字段,並顯示為 姓名,實現字符串的連接使用concat函數 SELECT CONCAT(empname, last_name) 全名 FROM emp;
結果圖:

tips:mysql中的『+』號不具備拼接字符串的特性,需要單獨利用拼接字符串的函數concat(),來完成拼接功能。
10、【補充】concat函數
功能:拼接字符串
select concat(字符1,字符2,字符3,…..)
11、【補充】ifnull函數
功能:判斷某字段或表達式是否為null,如果為null 返回指定的值,否則返回原本的值
select ifnull(bonus,0) from emp;
12、【補充】isnull
功能:判斷某字段或表達式的值是否為null,如果是,則返回為1,如果不是,則返回為0
進階2:條件查詢
一、語法
select 查詢列表 from 表名 where 篩選條件;
二、篩選條件的分類
1、簡單條件運算符
> < = <>不等於 >= <= <=>安全等於
2、邏輯運算符
&& and
|| or
! not
3、模糊查詢
我們着重對於模糊查詢進行詳細介紹,下面給出相應的案例:
(1)like:一般搭配通配符使用,可以判斷字符型和數值型
通配符:%任意多個字符,_任意單個字符
/* LIKE 特點: 1.一般和通配符搭配使用 通配符: % 任意多個字符,包含0個字符 _ 任意單個字符 */ #案例1:查詢員工名中帶有字母a的員工 SELECT * FROM emp WHERE empname like '%a%'; #案例2:查詢員工名中第三個字符為i,第五個字符為e的員工名和工資 SELECT empname,salary from emp WHERE empname LIKE '__i_e%'; #案例3:查詢員工名中第二個字符為_的員工名,包含有特殊字符 SELECT empname FROM emp WHERE empname LIKE '_$_' ESCAPE '$';#可以使用任意字符與使用escape關鍵字一起使用,將此字符改變為轉義字符;或者使用斜杠轉義:empname LIKE '__'
查看一下結果圖:
案例1結果:

案例2結果:

案例3結果:

tips:這裡主要說明一下案例3結果,由於我們的數據集中,並沒有員工名中包含有『_』的員工。所以最後查詢的結果為空,而案例3的意義在於說明對於轉義字符的使用問題。我們除了使用斜杠之外,增加了一種使用escape關鍵字的方法。最後的結果中,並沒有報語法錯誤,所以證明這個關鍵字是可以使用的。
(2)between and
#2.between and /* 1.使用between and 可以提高語句的簡潔度 2.包含臨界值 3.兩個臨界值不要調換順序 */ #案例1.查詢員工薪資在2000到5000之間的員工信息 select * FROM emp where salary>=2000 AND salary<=5000; #------------------- select * FROM emp WHERE salary between 2000 and 5000;
兩個查詢的結果集相同,如下所示:

tips:使用between and進行模糊查詢的時候,我們需要注意兩個數值之間的順序,而且between and模糊查詢最後代表的是一個範圍內的結果。
(3)in
/* 含義:判斷某字段的值是否屬於in列表中的某一項 特點: (1)使用in提高語句的簡潔度 (2)in列表的值類型必須一致或兼容 '123' 123 (3)列表中不支持通配符的使用 */ #查詢:查詢員工的姓名為tom1、tom、ceimeng的員工的名字和部門編號 SELECT empname,deptId FROM emp where empname = 'tom1' OR empname = 'tom' OR empname = 'ceimeng'; #------------------------------------------ SELECT empname,deptId FROM emp where empname IN('tom1','tom','ceimeng');
兩個查詢的結果集也相同:

tips :關鍵字in的模糊查詢更加類似於一種列表清單,在此列表清單內的數據都會被列舉出來。
(4)is null 和 is not null:用於判斷null值
/* =或<>不能用於判斷null值 is null 或者 is not null 可以判斷null值 #is null pk <=> is null :僅僅可以判斷null值,可讀性較高,建議使用 <=> :既可以判斷null值,又可以判斷普通的數值,可讀性較低 */ #案列1:查詢沒有獎金的員工名和獎金 SELECT empname,bonus FROM emp WHERE bonus is NULL; #---------------- #安全等於 <=> SELECT empname,bonus FROM emp WHERE bonus <=> NULL;
查看一下結果集:

tips:案例中也給出了兩種判斷null方法,供各位同學選擇~
進階3:排序查詢
基本的語法與上面的兩種相同,主要是使用order by關鍵字
#進階3:排序查詢 /* 引入: select * FROM emp; 語法: select 查詢列表 FROM 表 【where 篩選條件】 ORDER BY 排序列表 【asc|DESC】 特點: 1、asc代表的是升序,desc代表的是降序 如果不寫,默認的是升序 2、order by字句中可以支持單個字段、多個字段、表達式、函數、別名 3、order by字句一般是放在查詢語句的最後面,limit字句除外 */ #案列1:查詢薪資>=2000的員工信息,按生日進行排序【添加篩選調價】 SELECT * from emp where salary >= 2000 ORDER BY birthday DESC; #案列2:按年薪的高低顯示員工的信息和 年薪【按表達式排序】 SELECT *,salary+IFNULL(bonus,0) '年薪' FROM emp ORDER BY salary+IFNULL(bonus,0) DESC; #案例3:查詢員工信息,要求先按照薪資升序,再按照員工編號降序【按多個字段進行排列】 SELECT * FROM emp ORDER BY salary ASC,id DESC;
在上面給出了3個案例,最後的結果如下所示:
案例1:

案例2:

案例3:

tips:上面的三個案例基本涵蓋了我們經常使用到的幾種排序情況,通過總結,我們可以發現,order by子句的使用方法與select子句的使用方法基本一致,主要差別在於使用的位置在整個語句的後面。
進階4:常見函數
一、基本概念
類似於java的方法,將一組邏輯語句封裝在方法體中,對外暴露方法名。
好處:
1、隱藏了實現細節
2、提高代碼的重用型調用:select 函數名(實參列表)【from 表】;
特點:
1、叫什麼(函數名)
2、幹什麼(函數功能)
分類:
1、單行函數 如 CONCAT、length、ifnull
2、分組函數 功能:做統計使用、聚合函數、組函數
二、單行函數
(1)字符函數
length:計算字符串長度
concat:拼接字符串
substr:截取從指定索引後面所有字符,或者,截取從指定索引處,指定字符長度的字符。注意:索引是從1開始的。
instr:返回子串第一次出現的索引,如果找不到返回0。
trim:去除子串前後的空格
upper、lower:將所有的字符串全部轉換為大寫或者小寫
lpad、rpad:用指定的字符實現左(或右)填充指定長度
replace :替換指定的字符串
(2)數學函數
round:四捨五入,可以指定保留小數點後面多少位
ceil:向上取整,返回>=改參數的最小整數
floor:向下取整,返回<=該參數的最大整數
truncate:從小數點後面第幾位開始截斷
mod:取余函數
對於取余函數我們需要注意一下其內部的計算法則,以避免在負數取余的時候犯錯。
/* 取余函數的底層運算 mod(a,b) : a-a/b*b MOD(-10,-3) :-10-(-10)/(-3)*(-3)=-10-3*(-3)=-1 */ select MOD(-10,-3); SELECT -10%(-3);
tips:正因為上述的取余運算的底層法則,使得負數取余的時候,餘數依舊為負數。
(3)日期函數
NOW:顯示當前年月日時分秒
curdate:僅僅顯示當前的日期
curtime:僅僅顯示當前的時間
year、month、day、hour、minute、second:分別顯示相應的時間單位
str_to_date:將時間字符串通過指定的格式轉換為日期
date_format:將時間按照指定的格式轉化為字符串
(4)控制函數
if函數
#1.if函數:if else 的效果 SELECT empname,bonus, IF(bonus is NULL,'沒獎金,呵呵','有獎金,嘻嘻') 備註 FROM emp;
我們查看一下結果集:

tips:通過上面的結果集,我們可以明顯的看出,if函數類似於java中的三位運算符,當判斷條件為真時,輸出第一個結果,條件為假時,輸出第二個結果。
case函數
#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 */ /*案例:查詢員工的工資,要求 部門號=1,顯示的工資為1.1倍 部門號=2,顯示的工資為1.2倍 部門號=3,顯示的工資為1.3倍 部門號=4,顯示的工資為1.4倍 */ SELECT empname,salary 原始工資,deptId, CASE deptId WHEN 1 THEN salary*1.1 WHEN 2 THEN salary*1.2 WHEN 3 THEN salary*1.3 ELSE salary*1.4 END 新工資 FROM emp; #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 */ #案例:查詢員工的工資情況 /* 如果工資>10000,顯示的A級別 如果工資>5000,顯示的B級別 如果工資>1000,顯示的C級別 否則,顯示的D級別 */ SELECT empname,salary, CASE WHEN salary>10000 THEN 'A' WHEN salary>5000 THEN 'B' WHEN salary>1000 THEN 'C' ELSE 'D' END 工資等級 FROM emp;
用法一的結果:

用法二的結果:

tips:對於兩種case的用法,全部都已經展示在了代碼行中,各位同學自己查看即可哈!
三、分組函數
(1)基本功能
功能:用作統計使用,又稱為聚合函數或統計函數或組函數。
(2)分類
sum 求和、avg 平均值、max 最大值、min 最小值、count 計算個數
下面對這幾個函數進行簡單的介紹
/* 特點: 1、sum avg 一般用於處理數值型 max min count 可以處理任何類型 2、以上分組函數都忽略null值 3、可以和關鍵字distinct搭配使用,實現去重的運算 4、count函數的單獨介紹 一般使用count(*)用作統計行數 5、和分組函數一同查詢的字段要求是group by 後的字段 */ #1、和distinct搭配 SELECT COUNT(DISTINCT deptId) from emp; #2、count函數的詳細介紹 SELECT COUNT(*) from emp;#統計整張表中的所有行數,也可以通過在添加常量的方法來統計:SELECT COUNT(1) from emp; #效率: #MYISAM 存儲引擎下 , count(*)的效率高 #INNODB 存儲引擎下 , count(*)和COUNT(1)的效率差不多,比count(字段)要高一些
案例1結果圖:

案例2結果圖:

tips:通過案例1,我們主要說明一下去重關鍵字與統計函數的搭配使用。在對deptId進行計數的時候,可以計算有多少個部門id。
進階5:分組查詢
一、基本思想
在前面的進階過程中,我們一直是針對整張表格的數據進行。分組查詢主要是根據用戶的需求,對自己設定的類別進行單獨的統計計算。在分組查詢中主要使用group by關鍵字。
二、語法
SELECT 分組函數,列(要求出現在group by的後面)
FROM 表 【where 篩選條件】
GROUP BY 分組的列表
【order by 子句】
注意點:查詢列表必須特殊,要求是分組函數和group by 後出現的字段
三、特點
#進階5:分組查詢 /* 特點: 1、分組查詢中的篩選條件分為兩類 數據源 位置 關鍵字 分組前篩選 原始表 GROUP BY子句的前面 WHERE 分組後篩選 分組後的結果集 GROUP BY子句的後面 HAVING (1)分組函數做條件肯定是放在having子句中 (2)能用分組前篩選的,就優先考慮使用分組前篩選 2、group by子句支持單個字段分組,多個字段分組(多個字段之間用逗號隔開,沒有順序要求),表達式(使用的較少) 3、也可以添加排序(排序放在整個分組查詢的最後) */ #案例1:查詢每個部門的平均工資 SELECT round(avg(salary),2),deptId FROM emp GROUP BY deptId; #添加分組後複雜的篩選條件 #案例2:查詢部門編號>1的每個部門中,最低工資大於1000的部門編號是哪個,以及其部門的最低工資 SELECT deptId,MIN(salary) 部門最低工資 FROM emp WHERE deptId>1 GROUP BY deptId HAVING 部門最低工資>5000;
案例1結果:

案例2結果:

tips:
案例2中,首先要求部門編號大於1,這個篩選條件我們可以直接在原始表中進行,所以使用的是where關鍵字,得到了第一步篩選之後的表格——部門編號大於1的各個部門的最低工資。
但是根據案例中的要求,每個部門的最低工資需要大於1000,這個篩選是基於我們第一次篩選之後表格進行的,所以此時我們不能夠繼續使用where關鍵字,需要使用having關鍵字,表示我們對第一次篩選得到的表格進行第二次篩選。同時根據我們的代碼也可以發現,在使用having關鍵字的時候,我們還可以使用別名進行二次篩選。