Mysql04各種函式,加密,條件查詢
本章節主要說一下mysql的各種函式用法以及條件子查詢,廢話不多說,大家看的時候概念瀏覽一下就可以,重點看下面的例子程式碼。
Mysql函式
字串
數字
日期
字串函式
char_length(‘a中’) - 字元數
length(‘a中’) - 位元組數
concat(‘a’,‘b’,‘cde’,‘fff’) - 字串連線,其他資料庫可用 || 連線字串,‘abc’ || ‘def’
concat_ws(’;’,‘abc’,‘def’,‘ggg’) - 用分隔符連線字串
instr(‘abcdefgdef’,‘def’) - 返回第一個子串的位置,從1開始,找不到返回0
locate(‘abc’, ‘—abc—abc—abc-’) - 返回第一個子串的位置,從1開始,找不到返回0
locate(‘abc’, ‘—abc—abc—abc-’,5) - 從指定位置向後找
insert(‘abcdefghijkl’,2, 11, ‘—’) - 用子串取代從2位置開始的11個字元
lower(‘AdFfLJf’) - 變為小寫
upper(‘AdFfLJf’) - 變為大寫
left(‘AdFfLJf’,3) - 返回最左邊的三個字元
right(‘AdFfLJf’,3) - 返回最右邊的三個字元
lpad(‘abc’, 8, ‘’) - 左側填充,指定長度比源字串少,相當於left
rpad(‘abc’, 8, '
trim(’ a bc ') - 去除兩端空格
substring(‘abcdefghijklmn’, 3) - 從3位置開始的所有字元
substring(‘abcdefghijklmn’, 3, 6) - 從3位置開始的6個字元
repeat(‘abc’, 3) - 重複三遍abc
REPLACE(‘Hello MySql’,‘My’,‘Your’) - 子串替換
REVERSE(‘Hello’) - 翻轉字串
SPACE(10) - 返回10個空格
數字函式
select ceil(-3.14) - 向上取整
select floor(3.94) - 向下取整
select format(391.536, 2) - 數字格式化為字串,###,###.###,四捨五入,第二個引數為小數位數
select round(673.4974) - 四捨五入
select round(673.4974, 2) - 四捨五入到小數點後兩位
select round(673.4974, -2) - 四捨五入到百
TRUNCATE(234.31, 1) - 捨去至小數點後1位
abs(-12) – 絕對值,得到 12
日期函式
Select NOW() ; 返回當前的日期和時間
Select CURDATE() ; 返回當前的日期
Select CURTIME() ; 返回當前的時間
Select DATE(時間); 提取日期或日期/時間表達式的日期部分
Select TIME(時間) ; 提取日期或日期/時間表達式的時間部分
Select EXTRACT(欄位 From 日期) 返回日期/時間按的單獨部分
欄位的合法值:
MICROSECOND
SECOND
MINUTE
HOUR
DAY
WEEK
MONTH
QUARTER
YEAR
SECOND_MICROSECOND
MINUTE_MICROSECOND
MINUTE_SECOND
HOUR_MICROSECOND
HOUR_SECOND
HOUR_MINUTE
DAY_MICROSECOND
DAY_SECOND
DAY_MINUTE
DAY_HOUR
YEAR_MONTH
date_add(日期, interval數量 欄位) 給日期加上指定的時間間隔
例如Date_add(now(), interval 30 year)
Date_add(now(), interval -30 year)代表減去30年,跟下邊date_sub函式一樣
LAST_DAY(日期) - 返回當月最後一天
NULL 相關
IFNULL(資料1,資料2) - 資料1是null返回資料2;不是null返回資料1
coalesce(資料1,資料2,資料3,......) - 從左向右第一個不是null的資料
加密
md5()
常用的密碼加密方式,
返回 32個長度的16進位制數字字串
sha()
比md5更安全
多行函式
多行資料,運算產生一個結果
多行函式不能與其他欄位一起查詢
count() 行數
sum() 求和
avg() 求平均
max() 最大值
min() 最小值
多行函式會忽略null值
資料行數: count()
資料量非常大時,count()效率很低,可以把行數另存在一張表中,定期更新
分頁查詢
沒有標準 sql
不同資料庫,提供不同的分頁查詢方式
Mysql 提供一個 limit語法
limit 5 - 前5條
limit 0,5 - 0行(第一行)開始的5條
limit 5,5 - 第六行開始的5條
limit 10,5 - 第十一行開始的5條
在資料量非常大時,
limit a,b效率非常低
limit a 效率較高
程式中計算起始行: (頁數-1)每頁行數
最大頁數:(count()/每頁行數) 再向上取整
group by 子句
多行函式的分組計算
只在求多行函式運算時,使用group by
Having子句
對多行函式計算結果進行過濾
where 和 having 區別:
where 過濾普通條件
having 過濾多行函式結果
having 必須跟在group by後面
select查詢語句結構順序
select
distinct – 去除重複
from
where
group by – 分組求多行函式
having – 多行函式過濾
order by – 排序放到最後
子查詢
在查詢語句中,巢狀的查詢
where後面的子查詢
from 後面的子查詢
select 查詢列表中的子查詢
條件子查詢
子查詢的查詢結果,作為另一個查詢的過濾條件
單值子查詢
=
> >=
< <=
多值子查詢
in
> all 比最大的大
> any 比最小的大
多列子查詢
(a,b) =
(a,b) in
練習
1*
連線first_name,last_name
select concat_ws(' ',first_name,last_name) name
from employees;
2*
名字中包含‘en’
like '%en%'
select
first_name
from
employees
where locate('en',first_name)<>0;
--找到first_name 中含en的名字
3*
select insert('adgfddrshgtersh',3,4,'***');
--把從第三個開始的後四個字元換成*
4*
frist_name左側4個字元,轉成大寫
phone_number右側4個字元
select
upper(left(first_name)) a,
lower(phone_number,4) b
from
employees;有疑問
5*
連結first——name,last——name
中間的空格對齊
select
concat(lpad(first_name,20,' '),' ',last_name)
from
employees;
6*
email由first_name 首字元和last_name組成
找email從第二個字元到末尾字元
與last_name不相等
select
first_name,last_name,email
from
employees
where
substring(email,2)<>last_name;
7*
電話號碼當中‘44’替換成‘88’
select
employee_id,
first_name,
phone_number,
replace(phone_number,'44','88') tel
from
employees;
//1. 數字函式測試
select ceil(3.14);
select ceil(-3.14);
select round(3.14);
select round(3.1415926, 3);保留三維小數
select format(12345.9876, 2);保留兩位小數
//2. 漲工資 11.37%,向上取整到 10 位
//ceil()向上取整,不能指定位數
//truncate()先加10,再截斷到10位
select
employee_id,
first_name,
salary,
ceil(salary/10)*10 sal
from
employees;
//3. 日期函式測試
//-- 系統時間
Select now();
Select curdate();
Select curtime();
// -- 從日期中提取
select date(now());
select time(now());
select extract(year from now());
select extract(month from now());
select extract(day from now());
select extract(week from now());
// -- 指定欄位加一個值
Select date_add(now(), interval 10 year);
Select date_add(now(), interval -10 year);
// -- 間隔天數
Select datediff(now(), '1996-7-12');
Select datediff('1996-7-12', now());
Select abs(datediff('1996-7-12', now()));
// -- 日期格式
Select date_format(now(), '%m/%d/%Y %H:%i:%s');
Select date_format(now(), '%Y年%m月%d日');
// -- 當月最後一天
select last_day(now());
select last_day('2016-2-6');
//4. 入職30年以上的員工
Date_add(now(), interval -30 year)
select
employee_id,
first_name,
salary,
hire_date
from
employees
where
hire_date<date_add(now(), interval -30 year);
-- datediff(now(), hire_date)>30*365+7;
//5. 1997年上半年入職的人
select
employee_id,
first_name,
hire_date
from
employees
where
hire_date between '1997-1-1' and '1997-6-30';
-- extract(year from hire_date)=1997 and extract(month from hire_date)<7
//6. 不論哪一年,所有1月份入職的人
select
employee_id,
first_name,
hire_date
from
employees
where
extract(month from hire_date)=1;
//7. 查詢員工,沒有主管顯示“沒有主管”,
//沒有部門顯示“沒有部門”
Select
employee_id,
first_name,
ifnull(manager_id, '沒有主管') manager_id,
coalesce(department_id, '沒有部門') department_id
from
employees;
//8. 查詢年薪,薪水*(1+提成)*12
select
employee_id,
first_name,
salary,
salary*(1+ifnull(commission_pct, 0))*12 sal
from
employees;
//9. 加密函式測試
select md5('123456');
select sha('123456');
//10. 多行函式測試
select
sum(salary),
count(salary),
avg(salary),
max(hire_date),
min(salary)
from
employees;
//11. 多行函式忽略 null 值測試
select
count(commission_pct) count,
sum(commission_pct) sum,
sum(commission_pct)/35 avg1,
avg(commission_pct) avg2,
avg(ifnull(commission_pct, 0)) avg3
from
employees;
//12. 用 count() 求資料行數
select count(*) from employees;
//13. 1997 年入職的人數
select count(*) from employees
where hire_date between '1997-1-1' and '1997-12-31';
-- where extract(year from hire_date)=1997;
//14. 50 部門的人數
select count(*) from employees
where department_id=50;
//15. 最後進公司的人的入職時間
select max(hire_date) from employees;
//16. 122號員工是個主管,他的手下有多少人
Select count(*) from employees
where manager_id=122;
//17. 分頁查詢員工,每頁10行
select
employee_id,
first_name,
salary
from
employees
-- limit 10;
-- limit 10,10;
-- limit 20,10;
limit 100,10;
//18. 每個部門的人數
select department_id, count(*)
from employees
where department_id is not null
group by department_id;
//19. 每個部門中,每個主管的手下人數
//部門 主管 人數
1 100 5
2 120 3
2 140 5
2 150 2
select
department_id,
manager_id,
count(*)
from
employees
where
department_id is not null and
manager_id is not null
group by
department_id,
manager_id;
//20. 每種工作的平均工資
select
job_id,
avg(salary)
from
employees
group by
job_id;
//21. 每年的入職人數
提取年號進行分組
select
extract(year from hire_date) year,
count(*)
from
employees
group by
year;
//22. 只有一個人的部門
select
department_id, count(*) c
from
employees
where
department_id is not null
group by
department_id
having
c=1;
//23. 平均工資大於10000的工作
select
job_id,
avg(salary) a
from
employees
group by
job_id
having
a>10000;
//24. 哪些年只有一個人入職
select
extract(year from hire_date) year,
count(*) c
from
employees
group by
year
having
c=1;
//25. 拿最低工資的員工資訊
Id 名字 工資
1 abc 2000
2 def 2000
3 ghi 2200
4 … …
分兩步:
//1. 求出最低工資值
//2. 用最低工資過濾查詢員工資訊
select
employee_id,
first_name,
salary
from employees
where salary=
(select min(salary) from employees);
26. 工資低於107人的平均工資
select
employee_id,
first_name,
salary
from employees
where salary<
(select avg(salary) from employees);
//27. 只有一個人的部門中的員工資訊
分兩步:
1)分組過濾,得到1個人的部門的部門id
2)根據部門id過濾員工資訊
select employee_id,first_name,department_id
from employees
where department_id in
(select department_id
from employees
where department_id is not null
group by department_id
having count(*)=1);
//28. 每個部門拿最高工資的員工資訊
//分兩步:
// 1)分組求部門最高工資
// 2)用部門和工資值來過濾員工
select employee_id,salary,department_id
from employees
where (department_id, salary) in
(select department_id, max(salary)
from employees
where department_id is not null
group by department_id);