1. 程式人生 > >單表查詢——詳解

單表查詢——詳解

一 語法

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