SQL 單表查詢

說明

一些說明

本文中所有中括號擴起的文字均代表可以替換的文字(包括中括號本身)
例如在我博客中的:

select [字段1],[字段2],...,[字段n] from [表名] where [查詢條件];

在實際使用時,可以寫作:

select name,age from users where id=3;

表結構

users表

工號 姓名 性別 年齡 職位 辦公電話 手機號
201215121 李勇 40 主管 13650 13365245865
201215122 劉晨 29 收銀員 13622 12535468521
201215123 王敏 29 會計 (Null) 17685324586
201215124 劉柳 42 總監 13623 19658245753
201215125 王輝 29 會計 (Null) 16698532547

如上users表所示,

  1. users叫做表名
  2. “工號”、“姓名”、“性別”、“年齡”和“職位”等叫做一個字段
  3. 該表的一行(例如:201215122 劉晨 女 29 收銀員 13622 12535468521)叫做一個記錄

1. 基本查詢操作

1.1. 基本語法

表的查詢,即查詢表中的數據記錄,表的查詢操作是SQL的基本數據操作之一,也是使用頻率最高、最重要的數據操作。

一個一般的查詢語法如下:

select [字段1],[字段2],...,[字段n] from [表名] where [查詢條件];

關鍵字解釋:

select: 查詢語句的起始關鍵字,表示該操作爲查詢操作
from: 後接數據源,表示在[表名]中查詢[字段i]
where: 後接查詢條件,表示要對查詢做的限制,該操作可以幫助數據庫使用者做精確的查找

1.2. * 查詢所有數據

查詢所有字段會把表內所有的數據都查詢出來,在select語句中使用星號" * "通配符來查詢表中的所有字段

語法爲:

select * from [表名];

例如:

select * from users; --表示從users表中查詢所有字段,

查詢結果爲:
在這裏插入圖片描述

1.3. as 給字段取別名

給字段取別名的意義在於可以清晰的展示某一字段所表示的內容,例如表中有一列“月工資”,要計算“年工資”時可將月工資12,這時候sql會顯示該字段的字段名爲“月工資12”,這對查詢結果的展示很不友好,通常情況下都會給它取一個別名。

取表名的可以使用“as”關鍵字,或者直接在字段後面接“"[別名]"”
語法爲:

select [字段名] as "[別名]", [字段名]"[別名]" from users;

例如下例:

select 工號, 工號 as "工", 姓名, 姓名"姓" from users;

在這裏插入圖片描述

1.4. distinct 消除重複

如果查詢結果中出現重複數據,可用關鍵字“distinct”消除,若沒有加上“distinct”關鍵字,查詢結果將默認展示重複數據。

需要注意的是,“distinct”關鍵字是作用於所有字段的組合,只有在所有字段值都重複的情況下,纔會消除重複。

語法如下:

select distinct [字段1],[字段2],...,[字段n] from [表名]

例如:

select 姓名,性別,年齡,職位 from users;
select distinct 姓名,性別,年齡,職位 from users;

左邊是未加distinct關鍵字的查詢結果,右邊是加上distinct關鍵字的查詢結果
在這裏插入圖片描述

1.4. 運算符

SQL提供的基本算術運算符有:

+ :加法
- :減法
* :乘法
/ :除法
% :取餘

SQL的算術運算符可以在列、常量之間運算,例如:

select 姓名, 年齡, 年齡+2, 年齡*2, 年齡*2, 年齡/2, 年齡%2 from users;

查詢結果爲:
在這裏插入圖片描述
要注意的是,運算符也是有優先級的,優先級規則與我們的數學運算符號規則一致。

2. where 條件查詢

在select語句中,可以通過where子句,對數據進行過濾,其語法格式爲

select [字段1],[字段2],...,[字段n] from [表名] where [查詢條件];

例如:

-- 篩選出年齡大於30的人
select 姓名, 年齡 from users where 年齡 > 30;

在這裏插入圖片描述

2.1. where中的比較運算符

比較運算符 作用
= 等於 <> 不等於
> 大於 < 小於
>= 大於等於 <= 小於等於
between [值1] and [值2] 介於[值1]和[值2]之間 in([值1], [值2],…, [值n]) 包含在[值1], [值2],…, [值n]之中
like 條件匹配(%:匹配多個字符,_:匹配一個字符) [值] is null 判斷[值]是否爲空

例如:

-- 查詢年齡不等於40的人
select 姓名, 年齡 from users where 年齡 <> 40;

在這裏插入圖片描述

-- 查詢年齡介於20到30之間的人
select 姓名, 年齡 from users where 年齡 between 20 and 30;

在這裏插入圖片描述

-- 匹配姓名中第一個字是‘劉’,第二個字隨意的人
select 姓名 from users where 姓名 like '劉_';

在這裏插入圖片描述

2.2. where中的邏輯運算符

邏輯運算符 作用
[表達式1] and [表達式2] 兩個表達式都爲true,才返回true ,否則返回false
[表達式1] or [表達式2] 兩個表達式其中之一爲true,就返回true,兩個都爲false,才返回false
not [表達式] 若表達式爲true,則返回false,若表達式爲false,則返回true

例如:

-- 找出年齡大於30的男性
select 姓名, 年齡, 性別 from users where 性別='男' or 年齡>30;

在這裏插入圖片描述

2.3. 排序

對查詢結果進行排序使用order by 關鍵詞

語法:

select [字段1], [字段2],..., [字段n] 
	from [表名] 
	order by [字段名1] [排序方式], [字段名2], [排序方式],..., [字段名n] [排序方式];

排序方式有兩種:

  1. asc 順序排列 (從小到大)
  2. desc 逆向排列 (從大到小)

例如:

-- 先按年齡順序排列,再將重複值按照工號逆序排列
select 工號, 姓名, 年齡 from users order by 年齡 asc, 工號 desc;

在這裏插入圖片描述

3. 常用函數

3.1. 字符串函數

函數 功能
concat([字符串1],[字符串2],…,[字符串n]) 連接字符串
group_concat([字段]) 對分組後的字段進行連接
insert([字符串1], [下標], [個數], [字符串2]) 將[字符串1]中從[下標]開始的[個數]個字符替換爲[字符串2]
lower([字符串]) 將[字符串]中的字母轉換爲小寫
upper([字符串]) 將[字符串]中的字母轉換爲大寫
length([字符串]) 計算[字符串]的字節長度
char_length([字符串]) 計算[字符串]的字符長度
lpad([字符串1], [長度], [字符串2]) 在[字符串1]的左邊填充[字符串2],使字符串長度達到[長度]
rpad([字符串1], [長度], [字符串2]) 在[字符串1]的右邊填充[字符串2],使字符串長度達到[長度]
trim([字符串]) 去掉[字符串]首尾的空格
repeat([字符串],[次數]) 將[字符串]重複[次數]次
replace([字符串1], [字符串2], [字符串3]) 用[字符串3]替換[字符串1]中所有的[字符串2]
substring([字符串], [下標], [長度]) 返回[字符串1]中從[下標]位置其長度爲[長度]的子串

舉例:

-- concat(工號,姓名)連接字段`工號`和`姓名`
select 工號, 姓名, concat(工號,姓名) from users; 

在這裏插入圖片描述

--lpad(姓名, 5, 'X')在姓名字段的左邊填充字符'L',使其字符長度達到5
--rpad(姓名, 5, 'X')在姓名字段的右邊填充字符'R',使其字符長度達到5
select lpad(姓名, 5, 'L'),rpad(姓名, 5, 'R') from users; 

在這裏插入圖片描述

3.2. 數值函數

函數 功能
abs([數值]) 返回[數值]的絕對值
ceil([數值]) 返回不小於[數值]的最小整數值
floor([數值]) 返回不大於[數值]的最小整數值
mod([數值1], [數值2]) 返回[數值1]/[數值2]的模
rand() 返回一個0~1之間的隨機數
round([數值1], [數值2]) 返回[數值1]四捨五入後保留[數值2]位小數的值
truncate([數值1], [數值2]) 返回[數值1]截斷後保留[數值2]位小數的值

例如:

-- 返回不小於0.8、-0.8和不大於0.8、-0.8的數值
select ceil(0.8), ceil(-0.8), floor(0.8), floor(-0.8) from users; 

在這裏插入圖片描述

-- round(3.14159,3)返回3.14159四捨五入後保留3位小數的值
-- truncate(3.14159,3)返回3.14159截斷後保留3位小數的值
select round(3.14159,3), truncate(3.14159,3) from users; 

在這裏插入圖片描述

3.3. 日期和時間函數

函數 功能
curdate() 返回當前日期
curtime() 返回當前時間
now() 返回當前的日期和時間
year([日期]) 計算[日期]的年份
monthname([日期]) 計算[日期]的月份,並返回其英文名
week([日期]) 計算[日期]爲一年中的第幾周
hour([時間]) 計算[時間]的小時值
minute([時間]) 計算[時間]的分鐘值
date_format([日期],[格式]) 將[日期]按[格式]返回
date_add([日期或時間],interval [時間間隔] [間隔類型]) 返回一個[日期或時間]後接一個[時間間隔]的時間值
datediff([時間1],[時間2]) 計算[時間1]和時間[2]之間的間隔天數

例如:

select now(), 
	   year(now()), monthname(now()), week(now()), 
       hour(now()), minute(now()); 

在這裏插入圖片描述

3.3.1. date_format()函數
格式 描述 格式 描述
%M 英文月名 %j 該日期所在一年中的第幾天(000-366)
%b 英文月名縮寫 %D 該日期所在一月中的第幾天(帶次序1st,2nd,…,31th)
%c 月數(0-12) %e 該日期所在一月中的第幾天(0-31)
%m 月數(01-12) %d 該日期所在一月中的第幾天(00-31)
%k 該時間所在的小時(0-23) %i 該時間所在一小時中的分鐘數(00-59)
%H 該時間所在的小時(00-23) %f 該時間所在一秒中的微秒數
%h 該時間所在一天中的小時(01-12) %a 該時間所在的星期名的英文縮寫
%I 該時間所在一天中的小時(01-12),同%h

例如:

select now(), date_format(now(), '%M %m %D'); 

在這裏插入圖片描述

3.3.2. date_add()函數
間隔類型 描述 間隔類型 描述
microsecond 微秒 second
minute 分鐘 hour 小時
day week 星期
month quarter 季度(一個季度三個月)
year second_microsecond 秒+微秒(寫成浮點數形式
例如10.1表示間隔10秒加1微秒)
minute_microsecond 分+微秒 minute_second 分+秒
hour_microsecond 小時+微秒 hour_second 小時+秒

例如:

-- 間隔一個季度
select now(), date_add(now(), interval 1 quarter); 

在這裏插入圖片描述

-- 間隔1分2秒
select now(), date_add(now(), interval 1.2 minute_second); 

在這裏插入圖片描述

3.4. 流程控制函數

3.4.1. if 流程函數

根據表達式的真假值做出判斷。
語法:

-- 如果[表達式]爲真,則返回[true返回值],否則返回[false返回值]
if ([表達式], [true返回值], [false返回值]);

例如:

-- 若字段值爲‘劉晨’,則返回‘是’,否則返回‘否’
select 姓名, if(姓名='劉晨', '是', '否') from users; 

在這裏插入圖片描述

3.4.2. ifnull 流程函數

ifnull用於判斷表達式是否爲空。
語法:

-- 若[表達式1]不爲null,就返回[表達式1]的值,若[表達式1]爲null,就返回[表達式2]的值
ifnull([表達式1], [表達式2])

例如:

-- (左圖) 查詢某單位人員的聯繫方式,有些人沒有辦公電話,只有手機號,這時會出現信息冗餘
select 姓名, 辦公電話, 手機號 from users

-- (右圖) 若使用ifnull()函數來處理,可以消除這些信息冗餘
-- ifnull(辦公電話, 手機號) 若有辦公電話,則顯示辦公電話,若沒有辦公電話,就用手機號代替
select 姓名, ifnull(辦公電話, 手機號) from users

在這裏插入圖片描述

3.4.3. case 流程函數

case流程函數可以幫助數據庫使用人員根據情況從多個選項中作出選擇。

語法:

-- case表達式可以根據[表達式1]的結果[值1]、[值2]、...、[值n]
-- 返回相應的[返回值1]、[返回值2]、...、[返回值n]
-- 如果[表達式1]的結果不在[值1]、[值2]、...、[值n]中,則返回[默認返回值]
case [表達式1]
	when [1] then [返回值1]
	when [2] then [返回值2]
	...
	when [值n] then [返回值n]
	else [默認返回值]
end

例如:

-- 用case表達式對性別進行中英文轉換
select 姓名, 性別,
	case 性別
	when '男' then 'male'
	when '女' then 'female'
	else 'unknown'
end
from users

在這裏插入圖片描述

3.5. 聚合函數

聚合函數用於對一組數進行運算,然後返回一個結果,需要注意的是,除了count()以外,其他的聚合函數在計算時會忽略null值。

常用的聚合函數有:

聚合函數 作用
count([列名]) 計算某一列有多少行
avg([列名]) 計算某一列數值的平均值
sum([列名]) 計算某一列數值的和
max([列名]) 求出某一列的最大值
min([列名]) 求出某一列的最小值

例如:

select count(*), avg(年齡), sum(年齡), max(年齡), min(年齡) from users

在這裏插入圖片描述

3.6. 數據庫屬性函數

屬性函數 功能
database() 返回當前數據庫名
version() 返回當前數據庫版本
user() 返回當前登錄用戶的用戶名
inet_aton([IP地址]) 返回IP地址的數字表示
inet_ntoa([IP數]) 將IP的數字表示轉換爲IP地址
password([密碼]) 返回加密後的[密碼]
md5([字符串]) 返回[字符串]的MD5值(32位的16進制串)

例如:

-- IP地址'192.168.1.1'與其數字表示的相互轉換
select inet_aton('192.168.1.1'), inet_ntoa(3232235777);

在這裏插入圖片描述

4. group by 分組查詢

分組查詢可以將值相同的字段分在同一個組,常和各種函數一起使用。關鍵詞是group by,寫在where子句之後

如果要對分組後的結果進行條件過濾,要使用having關鍵字,having就是group by中的where,但是having子句中可以使用聚合函數,where中不行。

語法:

select [字段],[函數1],[函數2],...,[函數n] 
	from [表名] 
	group by [字段] 
	having [表達式];

需要注意的是,select中兩個的[字段]必須相同,因爲對數據按[字段]進行分組以後,其他的字段都會被打亂,無法直接查詢出來。

例如:

-- (右圖)對分組後的姓名字段值進行連接,並統計每一個分組的年齡總和
select 年齡, group_concat(姓名), sum(年齡) from users group by 年齡;

在這裏插入圖片描述

-- 帶having子句的分組查詢
-- 首先對分組後的姓名字段值進行連接,並統計每一個分組的年齡總和
-- 然後從中選出年齡小於30的分組,返回
select 年齡, group_concat(姓名), sum(年齡) 
	from users 
	group by 年齡
	having 年齡 < 30;

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章