1. 程式人生 > >MySQL--單表查詢、多表查詢簡單概述

MySQL--單表查詢、多表查詢簡單概述

表的前期準備:

create table emp(
  id int not null unique auto_increment,
  name varchar(20) not null,
  sex enum('male','female') not null default 'male', #大部分是男的
  age int(3) unsigned not null default 28,
  hire_date date not null,
  post varchar(50),
  post_comment varchar(100),
  salary double(15,2),
  office int, #一個部門一個屋子
  depart_id int
);

#插入記錄
#三個部門:教學,銷售,運營
insert into emp(name,sex,age,hire_date,post,salary,office,depart_id) values
('jason','male',18,'20170301','張江第一帥形象代言',7300.33,401,1), #以下是教學部
('egon','male',78,'20150302','teacher',1000000.31,401,1),
('kevin','male',81,'20130305','teacher',8300,401,1),
('tank','male',73,'20140701','teacher',3500,401,1),
('owen','male',28,'20121101','teacher',2100,401,1),
('jerry','female',18,'20110211','teacher',9000,401,1),
('nick','male',18,'19000301','teacher',30000,401,1),
('sean','male',48,'20101111','teacher',10000,401,1),

('歪歪','female',48,'20150311','sale',3000.13,402,2),#以下是銷售部門
('丫丫','female',38,'20101101','sale',2000.35,402,2),
('丁丁','female',18,'20110312','sale',1000.37,402,2),
('星星','female',18,'20160513','sale',3000.29,402,2),
('格格','female',28,'20170127','sale',4000.33,402,2),

('張野','male',28,'20160311','operation',10000.13,403,3), #以下是運營部門
('程咬金','male',18,'19970312','operation',20000,403,3),
('程咬銀','female',18,'20130311','operation',19000,403,3),
('程咬銅','male',18,'20150411','operation',18000,403,3),
('程咬鐵','female',18,'20140512','operation',17000,403,3)
;

#ps:如果在windows系統中,插入中文字元,select的結果為空白,可以將所有字元編碼統一設定成gbk

 

 

 

 

 

 

 

1、語法執行順序:

select id,name from emp where id >= 3 and id <= 6;

# 先後順序
from  # 確定到底是哪張表
where  # 根據過來條件 篩選條件
select  # 拿出篩選出來的資料中的某些欄位

select * from emp\G; # 當表字段特別多的時候 結果的排版可能會出現混亂的現象 你可以在查詢語句加入\G來規範查詢的結果

 

  

 

 

 

 

2、where約束條件# 1.查詢id大於等於3小於等於6的資料

select * from emp where id >= 3 and id <= 6;
select * from emp where id between 3 and 6;  # 這條語句等價於上面那條語句
# 2.查詢薪資是20000或者18000或者17000的資料
select id,name from emp where salary = 20000 or salary = 18000 or salary = 17000;
select id,name from emp where salary in (20000,18000,17000);
# 3.查詢員工姓名中包含o字母的員工姓名和薪資
# 模糊匹配 like
# %:匹配多個任意字元
# _:匹配一個任意字元
select name, salary from emp where name like '%o%';
# 4.查詢員工姓名是由四個字元組成的員工姓名與其薪資
# 5.查詢id小於3或者大於6的資料
select * from emp where id < 3 or id > 6;

  select * from emp where id not between 3 and 6;
  # 6.查詢薪資不在20000,18000,17000範圍的資料
  select id,name from emp where salary not in (20000,18000,17000);
  # 7.查詢崗位描述為空的員工名與崗位名 針對null判斷的時候只能用is 不能用=
  select name,post from emp where post_comment = Null;
  select name,post from emp where post_comment is Null;


MySQL對於大小寫是不敏感的


 

 

 

 

 

 

 

group by分組

# 1.按部門分組
    select * from emp group by post;
    分組之後應該做到最小單位是組,而不應該再展示組內的單個數據信息
    
    MySQL中分組之後 只能拿到分組的欄位資訊 無法直接獲取其他欄位資訊
    但是你可以通過其他方法(聚合函式)簡介的獲取

    如果你的MySQL不報錯 說明嚴格模式沒有設定 
    show variables like '%mode%';
    set session  當前視窗有效
    set global  全域性有效 
    set global sql_mode="strict_trans_tables,only_full_group_by";

select * from emp group by post; select id,name from emp group by post; select name from emp group by post; # 2.獲取每個部門的最高工資 聚合函式 max min avg sum count select post,max(salary) from emp group by post; 給欄位取別名 select post as '部門',max(salary) as '最高工資' from emp group by post; 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(age) from emp group by post; select post,count(salary) from emp group by post; select post,count(id) from emp group by post; select post,count(post_comment) from emp group by post; 在統計分組內個數的時候 填寫任意非空欄位都可以完成計數,推薦使用能夠唯一標識資料的欄位 比如id欄位 """ 聚合函式會自動將每一個分組內的單個數據做想要的計算,無需你考慮 """ # 3.查詢分組之後的部門名稱和每個部門下所有的學生姓名 select post,group_concat(name) from emp group by post; select post,group_concat('DSB',name) from emp group by post; group_concat()能夠拿到分組後每一個數據指定欄位(可以是多個)對應的值 select post,group_concat(name,": ",salary) from emp group by post; concat select concat("NAME: ",name),concat("SAL: ",salary) from emp; 小技巧: concat就是用來幫你拼接資料 concat 不分組情況下使用 group_concat 分組之後使用 # 查詢每個員工的年薪 select name,salary*12 from emp; # 剛開始查詢表,一定要按照最基本的步驟,先確定是哪張表,再確定查這張表也沒有限制條件,再確定是否需要分類,最後再確定需要什麼欄位對應的資訊 """ 你應該將每一步操作產生的結果都當成是一張新的表 然後基於該表再進行其他的操作 """ 1. 查詢崗位名以及崗位包含的所有員工名字group_concat 2. 查詢崗位名以及各崗位內包含的員工個數count 3. 查詢公司內男員工和女員工的個數count 4. 查詢崗位名以及各崗位的平均薪資avg 5. 查詢崗位名以及各崗位的最高薪資max 6. 查詢崗位名以及各崗位的最低薪資min 7. 查詢男員工與男員工的平均薪資,女員工與女員工的平均薪資avg """ 聚合函式 max min sum count avg只能在分組之後使用 如果一張表沒有寫group by預設所有的資料就是一組 """ 書寫順序 select from where group by 執行順序 from where group by select 8、統計各部門年齡在30歲以上的員工平均工資 # 先獲取年輕在30歲以上的員工 select post,avg(salary) from emp where age > 30 group by post; """ 寫sql語句的時候 一定不要一口氣寫完 前期先按照步驟一步步寫 寫一步查詢看一下結果然後基於當前結果再往後寫 """

 

 

 

 

 

having

跟where是一模一樣的 也是用來篩選資料
        但是having是跟在group by之後的
        where是對整體資料做一個初步的篩選
        而having是對分組之後的資料再進行一次針對性的篩選
1、統計各部門年齡在30歲以上的員工平均工資,
    並且保留平均工資大於10000的部門
    select post,avg(salary) from emp where age > 30 group by post having avg(salary) > 10000;
    select post,avg(salary) from emp where age > 30 group by post where avg(salary) > 10000;  # 報錯
    
    # 強調:having必須在group by後面使用
    select * from emp having avg(salary) > 10000;  # 報錯

    執行順序
    from 
    where
    group by
    having
    select

 

 

 

 

distinct去重

多重複的資料進行一個去重
    """
    去重必須資料是一模一樣的才能去重
    只要有一個不一樣 都不能算是的重複的資料
    """
    select distinct id,age from emp;
    
    
    
    執行順序
    from 
    where
    group by
    having
    select
    distinct
    

 

 

 

 

 

order by:排序

預設是升序 asc
        也可以變成降序  desc
        
    select * from emp order by salary;
    select * from emp order by salary asc;
    select * from emp order by salary desc;
    select * from emp order by age,salary;   # 先按照age做升序 age相同的情況下再按照salary做升序
    select * from emp order by age asc,salary desc;   # 先按照age做升序 age相同的情況下再按照salary做升序
    
    
    # 統計各部門年齡在10歲以上的員工平均工資,
    # 並且保留平均工資大於1000的部門,然後對平均工資進行排序
    select post,avg(salary) from emp where age > 10 group by post having avg(salary) > 1000 order by avg(salary);

 

 

 

 

 

limit:限制展示資料的條數

limit  限制展示資料的條數
    select * from emp limit 5;  # 只展示資料的五條
    select * from emp limit 5,5;  
    
    """
    當limit只有一個引數的時候  表示的是隻展示幾條
    當limit有兩個引數的時候   第一個引數表示的起始位置 第二個引數表示從起始位置開始往後展示的條數
    
    """
    # 查詢工資最高的人的詳細資訊
    # 先按照薪資排序
    # 再用limit限制 只取一條
    
    select * from emp order by salary desc limit 1;
    

 

 

 

 

正則:在程式設計中 只要看到reg開頭的  基本上都是跟正則相關的

select * from emp where name regexp '^j.*(n|y)$';

 

 

 

 

多表查詢:

"""
    表查詢分為兩大類
        1.聯表查詢
        2.子查詢
    """
    select * from emp,dep;   產生的結果是一個笛卡爾積
    
    
    # 查詢部門為技術部的員工及部門資訊
    
    
    
    有專門幫你做連表的方法
    內連線(inner join)
        
    左連線(left join)
    
    右連線(right join)
    
    全連線(union)  # 只要將左連線和右連線的sql語句 加一個union就變成全連線
    
        select * from emp left join dep on emp.dep_id = dep.id
        union
        select * from emp right join dep on emp.dep_id = dep.id;
            
    
    子查詢
        將一張表的查詢結果作為另外一個sql語句的查詢條件
        
    select name from dep where id = (select dep_id from emp where name = 'jason');
    
    # 2.每個部門最新入職的員工 
    # 思路:先查每個部門最新入職的員工,再按部門對應上聯表查詢
    
    select t1.id,t1.name,t1.hire_date,t1.post,t2.* from emp as t1
        inner join
        (select post,max(hire_date) as max_date from emp group by post) as t2
        on t1.post = t2.post
        where t1.hire_date = t2.max_date
        ;
    
    
    # 可以給表起別名
    # 可以給查詢出來的虛擬表起別名
    # 可以給欄位起別名

&n