單表查詢——詳解
阿新 • • 發佈:2018-11-26
一 語法
select distinct 查詢欄位1,查詢欄位2,。。。 from 表名
where 分組之前的過濾條件
group by 分組依據
having 分組之後的過濾條件
order by 排序欄位
limit 顯示的條數;
上面是語法定義順序,不是執行順序;
#使用函式的方式模擬語法順序;
def from(dir,file):
open('%s\%s' %(dir,file),'r')
return f
def where(f,pattern):
for line in f:
if pattern:
yield line
def group():
pass
def having():
pass
def distinct():
pass
def order():
pass
def limit():
pass
# 語法執行順序(如果直接寫後面的 前面關鍵字預設值=True)
def select():
res1=from()
res2=where(res1,pattern)
res3=group(res2,)
res4=having(res3)
res5=distinct(res4)
res6=order(res5)
limit(res6) #limit 本質是一個列印操作
???
select math as "級別",count(math)as "人數" from stu group by "級別" order by "人數" desc limit 0,3;
????
二 where過濾
select id,name from db39.emp where id >= 3 and id <= 6
select * from db39.emp where id between 3 and 6;
select * from emp where salary = 20000 or salary = 18000 or salary = 17000;
select * from emp where salary in (20000,18000,17000);
要求:查詢員工姓名中包含i字母的員工姓名與其薪資
select name,salary from db39.emp where name like '%i%'
要求:查詢員工姓名是由四個字元組成的的員工姓名與其薪資
select name,salary from db39.emp where name like '____';
select name,salary from db39.emp where char_length(name) = 4;
select * from db39.emp where id not between 3 and 6;
select * from emp where salary not in (20000,18000,17000);
要求:查詢崗位描述為空的員工名與崗位名
select name,post from db39.emp where post_comment is NULL;
select name,post from db39.emp where post_comment is not NULL;
————————————————————————————————————————————————————————————————————————————————————————
三 group by分組
#設定sql_mode為only_full_group_by,意味著以後但凡分組,只能取到分組的依據
mysql> set global sql_mode="strict_trans_tables,only_full_group_by";
#每個部門的最高工資
select post,max(salary) from emp group by post; 最大值
select post,min(salary) from emp group by post; 最小值
select post,avg(salary) from emp group by post; 平均值
select post,sum(salary) from emp group by post; 總和
select post,count(id) from emp group by post; 每個分組的人數
#group_concat(分組之後用)
select post,group_concat(name) from emp group by post;
select post,group_concat(name,"_SB") from emp group by post;
select post,group_concat(name,": ",salary) from emp group by post;
select post,group_concat(salary) from emp group by post;
# 補充concat(不分組時用)
select name as 姓名,salary as 薪資 from emp;
select concat("NAME: ",name) as 姓名,concat("SAL: ",salary) as 薪資 from emp;
# 補充as語法
mysql> select emp.id,emp.name from emp as t1; # 報錯
mysql> select t1.id,t1.name from emp as t1;
————————————————————————————————————————————————————————————————————————————————————————
# 查詢四則運算
select name,salary*12 as annual_salary from emp;
————————————————————————————————————————————————————————————————————————————————————————
分組練習
1. 查詢崗位名以及崗位包含的所有員工名字
select post,group_concat(name) from emp group by post;
2. 查詢崗位名以及各崗位內包含的員工個數
select post,count(id) from emp group by post;
3. 查詢公司內男員工和女員工的個數
select sex,count(id) from emp group by sex;
4. 查詢崗位名以及各崗位的平均薪資
select post,avg(salary) from emp group by post;
5. 查詢崗位名以及各崗位的最高薪資
6. 查詢崗位名以及各崗位的最低薪資
7. 查詢男員工與男員工的平均薪資,女員工與女員工的平均薪資
select sex,avg(salary) from emp group by sex;
8、統計各部門年齡在30歲以上的員工平均工資
select post,avg(salary) from emp where age >= 30 group by post;
————————————————————————————————————————————————————————————————————————————————————————
四 having過濾
having的語法格式與where一模一樣,只不過having是在分組之後進行的進一步過濾
即where不能用聚合函式,而having是可以用聚合函式,這也是他們倆最大的區別
1、統計各部門年齡在30歲以上的員工平均工資,並且保留平均工資大於10000的部門
select post,avg(salary) from emp
where age >= 30
group by post
having avg(salary) > 10000;
#強調:having必須在group by後面使用
select * from emp
having avg(salary) > 10000; #這是錯誤的
————————————————————————————————————————————————————————————————————————————————————————
五 distinct去重
select distinct post,avg(salary) from emp
where age >= 30
group by post
having avg(salary) > 10000;
————————————————————————————————————————————————————————————————————————————————————————
六 order by 排序
select * from emp order by salary asc; #預設升序排
select * from emp order by salary desc; #降序排
select * from emp order by age desc; #降序排
select * from emp order by age desc,salary asc; #先按照age降序排,再按照薪資升序排
# 統計各部門年齡在10歲以上的員工平均工資,並且保留平均工資大於1000的部門,
然後對平均工資進行排序
select post,avg(salary) from emp
where age > 10
group by post
having avg(salary) > 1000
order by avg(salary)
;
————————————————————————————————————————————————————————————————————————————————————————
七 limit 限制顯示條數
select * from emp limit 3;
select * from emp order by salary desc limit 1;
# 分頁顯示
select * from emp limit 0,5;
select * from emp limit 5,5;
————————————————————————————————————————————————————————————————————————————————————————
八 正則表示式
# MYSQL支援正則匹配
select * from emp where name regexp '^jin.*(n|g)$';
# 開啟正則
select * from emp where name regexp