Python-select 關鍵字 多表查詢 子查詢

sql 最核心的查詢語句!!!!增刪改單表查詢    select語句的完整寫法    關鍵字的書寫順序        執行順序多表查詢    笛卡爾積    內鏈接    左外鏈接    右外鏈接    全外鏈接        經過合併左外鏈接和右外鏈接子查詢    一個查詢包含另外一個查詢 被包含的叫子查詢    當一個查詢的結果 是另外一個查詢的條件時  這個查詢叫子查詢    子查詢須要用括號包起來====================================1.數據增刪改    增長  insert [into] 表名[(可選字段名)] values(一堆值1),(一堆值2),.....   into 能夠省略   表名後的字段能夠選   若是寫了 後面的values中的值必須與表名後的字段一一對應   若是沒寫 後面的values中的值必須與表的全部字段一一對應   values後面能夠給多組值 用逗號隔開    刪除  delete from 表名[where 條件]  條件不寫 是刪除全部記錄 是一行一行刪除   注意自增id 不會歸零  truncate 重建表  先記錄表結構 刪除整個表再從新建出來表 自增id 會歸零    更新數據    update 表名 set 字段名 = 值[,字段2 = 值2],[where 條件]    能夠一次性修改多個字段的值用逗號隔開    條件若是不寫 修改全部記錄2.單表查詢    不帶關鍵字的查詢    select  {1.*|2.字段名|3.四則運行|4.聚合函數} from 表名 [where 條件]    1.* 表示查詢全部字段    2.能夠手動要查詢的字段    3.字段的值能夠進行加減乘除運算    4.聚合函數,用於統計    where 是可選的    select 的完整語法        數據準備        create table stu(id int primary key auto_increment,name        char(10),math float,english float);        insert into stu values(null,"趙雲",90,30);        insert into stu values(null,"小喬",90,60);        insert into stu values(null,"小喬",90,60);        insert into stu values(null,"大喬",10,70);        insert into stu values(null,"李清照",100,100);        insert into stu values(null,"鐵柺李",20,55);        insert into stu values(null,"小李子",20,55);3 關鍵字的做用    distinct  去除重複數據 全部數據全都重複纔算重複    where  在逐行讀取數據時的一個判斷條件    group by  對數據分組    having   對分組後的數據進行過濾    order by 對結果排序    limit  指定獲取數據條數    完整的select 語句 語法,書寫順序是固定的 *****        select [distinct] * from 表名        [where        group by        having        order by        limit        ]    注意 在書寫時 必須按照這個順序來寫 !!! 可是順寫順寫不表明執行順序    關鍵字的執行順序 *****        from        where        group by        having        select        distinct        order by        limit        1.找到表:from        2.拿着where指定的約束條件,去文件/表中取出一條條記錄        3.將取出的一條條記錄進行分組group by,若是沒有group by,則總體做爲一組        4.將分組的結果進行having過濾        5.執行select        6.去重        7.將結果按條件排序:order by        8.限制結果的顯示條數    簡單查詢       定義顯示格式:        concat()函數用於拼接字符串        # 補充concat(不分組時用)        select name as 姓名,salary as 薪資 from emp;        select concat("NAME: ",name) as 姓名,concat("SAL: ",salary) as 薪資 from emp;       經過四則運算查詢            SELECT name, salary*12 FROM employee;            SELECT name, salary*12 AS Annual_salary FROM employee;            SELECT name, salary*12 Annual_salary FROM employee;        select            (case            when english + math > 120 then            concat(name," nice")            when english + math <= 130 then            concat(name," shit")            end        ) ,english,math from stu;    A, distinct去重        當全部字段的值都相同纔會去重        select distinct post,avg(salary) from emp                    where age >= 30                    group by post                    having avg(salary) > 10000;    B, where 條件    where字句中可使用:        1. 比較運算符:> < >= <= <> !=        2. between 80 and 100 值在10到20之間        3. in(80,90,100) 值是10或20或30        4. like 'egon%'            pattern能夠是%或_,            %表示任意多字符            _表示一個字符        5. 邏輯運算符:在多個條件直接可使用邏輯運算符 and or not        create table emp (id int,name char(10),sex char,dept char(10),job            char(10),salary double);            insert into emp values            (1,"劉備","男","市場","總監",5800),            (2,"張飛","男","市場","員工",3000),            (3,"關羽","男","市場","員工",4000),            (4,"孫權","男","行政","總監",6000),            (5,"周瑜","男","行政","員工",5000),            (6,"小喬","女","行政","員工",4000),            (7,"曹操","男","財務","總監",10000),            (8,"司馬懿","男","財務","員工",6000);        where後可用:            四則運算+-*/            ><=!            between and            in            not null            and or not            like            regexp            any/all  where 10>any(select age from emp)                     where 10>all(select age from emp)        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;    C, group by 分組查詢 *****        #一、首先明確一點:分組發生在where以後,即分組是基於where以後獲得的記錄而進行的        #二、分組指的是:將全部記錄按照某個相同字段進行歸類,好比針對員工信息表的職位分組,或者按照性別進行分組等        #三、爲什麼要分組呢?            取每一個部門的最高工資            取每一個部門的員工數            取男人數和女人數        小竅門:‘每’這個字後面的字段,就是咱們分組的依據        #四、大前提:            能夠按照任意字段分組,可是分組完畢後,好比group by post,            只能查看post字段,若是想查看組內信息,須要藉助於聚合函數        什麼是分組            把一個總體 分割爲多個部分        爲何分組            在數據庫中分組爲了統計 *****        分組後 組裏的詳細記錄就被隱藏起來了  不能直接查看            dept 一分組 變成三條記錄  每一個組中卻包含多條記錄 沒辦法顯示            必定要顯示的話            可使用group_concat(字段名)            能夠將多個值拼接成一個字符串        注意*****: 1.只有查看出如今group by 後面的字段, 其餘都被影藏了              2.聚合函數不能寫在where的後面  where最早執行 它的做用硬盤讀取數據並                過濾 覺得數據尚未讀取完 此時不能進行統計            聚合函數:count                    max /min                    avg                    sum        瞭解:            在mysql 5.6中 分組後會默認顯示 每組的第一條記錄 這是沒有意義的            5.7不顯示 由於5.7中 sql_mode中自帶  ONLY_FULL_GROUP_BY            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;        # 補充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;        八、統計各部門年齡在30歲以上的員工平均工資           select post,avg(salary) from emp where age >= 30 group by post;    聚合函數        #強調:聚合函數聚合的是組的內容,如果沒有分組,則默認一組        示例:            SELECT COUNT(*) FROM employee;            SELECT COUNT(*) FROM employee WHERE depart_id=1;            SELECT MAX(salary) FROM employee;            SELECT MIN(salary) FROM employee;            SELECT AVG(salary) FROM employee;            SELECT SUM(salary) FROM employee;            SELECT SUM(salary) FROM employee WHERE depart_id=3;    D, having過濾    HAVING與WHERE不同的地方在於!!!!!!        #!!!執行優先級從高到低:where > group by > having        #1. Where 發生在分組group by以前,於是Where中能夠有任意字段,可是絕對不能使用聚合函數。        #2. Having發生在分組group by以後,於是Having中可使用分組的字段,沒法直接取到其餘字段,可使用聚合函數        having的語法格式與where如出一轍,只不過having是在分組以後進行的進一步過濾        即where不能用聚合函數,由於數據尚未所有讀取,沒法統計.而having是能夠用聚合函數,這也是他們倆最大的區別        一、統計各部門年齡在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;    E, order by 排序用的     按單列排序        SELECT * FROM employee ORDER BY salary;        SELECT * FROM employee ORDER BY salary ASC;        SELECT * FROM employee ORDER BY salary DESC;     按多列排序:先按照age排序,若是年紀相同,則按照薪資排序        SELECT * from employee        ORDER BY age,        salary DESC;        asc 表示升序 是默認的        desc 表示降序        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)            ;    F, limit 限制顯示條數        limit a,b        limit 1,5        從1開始 到5結束 錯誤        從1開始 不包含1 取5條 正確        select * from emp limit 3;        select * from emp order by salary desc limit 1;        分頁查詢            每頁顯示3條  共有10條數據            if 10 % 3 == 0:                10 / 3            else:                10/3 +1            總頁數4            第一頁            select *from emp limit(0,3)            第二頁            select *from emp limit(3,3)    正表達式匹配       因爲like只能使用% 和 _ 不太靈活       能夠將like換爲 regexp 來使用正則表達式       select * from emp where name regexp '^jin.*(n|g)$';4.多表查詢 ******   數據準備    create table emp (id int,name    char(10),sex char,dept_id int);    insert emp values(1,"大黃","m",1);    insert emp values(2,"老王","m",2);    insert emp values(3,"老李","w",30);    create table dept (id int,name char(10));    insert dept values(1,"市場");    insert dept values(2,"財務");    insert dept values(3,"行政");    1.笛卡爾積查詢    select *from 表1,表n    查詢結果是        左表中的每條記錄 與右表中的每條記錄都關聯一遍        由於 他不知道什麼樣的對應關係是正確 只能幫你都對一遍        會產生一堆垃圾數據,須要進行過濾 where 從表的外鍵 =主表的主鍵        a表有m條記錄  b表有n條記錄        笛卡爾積結果爲m * n 記錄    須要本身篩選出正確的關聯關係    select *from emp,dept where emp.dept_id = dept.id;    2.內鏈接查詢inner join        把兩張表有對應關係的記錄鏈接成一張虛擬表 (就是笛卡爾積查詢)        內指的是可以匹配上的數據    select * from emp [inner] join dep on emp.dep_id = dep.id;    #應用:        select * from emp,dep where emp.dep_id = dep.id and dep.name = "技術"; # 不要用where作連表的活        select * from emp inner join dep on emp.dep_id = dep.id            where dep.name = "技術";    3.左外連接查詢left join        在內鏈接的基礎上,保留左邊沒有對應關係的記錄         左表數據所有顯示 右表只顯示匹配上的    select *from emp left join dept on emp.dept_id = dept.id;    4.右外連接查詢right join        在內鏈接的基礎上,保留右邊沒有對應關係的記錄        右表數據所有顯示 左表只顯示匹配上的    select *from emp right join dept on emp.dept_id = dept.id;    內和外的理解   內指的是匹配上的數據  外指的是沒匹配上的數據    5.全外鏈接        在內鏈接的基礎上,保留左、右邊沒有對應關係的記錄        左右兩邊的記錄徹底顯示     select *from emp full join dept on emp.dept_id = dept.id;  ##mysql不支持     union 合併查詢,去除重複數據  只能合併字段數量相同的表         select *from emp left join dept on emp.dept_id = dept.id         union         select *from emp right join dept on emp.dept_id = dept.id;     union all 不會去除重複數據    #補充:多表鏈接能夠不斷地與虛擬錶鏈接        查找各部門最高工資        select t1.* from emp as t1        inner join        (select post,max(salary) as ms from emp group by post) as t2        on t1.post = t2.post        where t1.salary = t2.ms        ;    三表查詢    create table stu(id int primary key auto_increment,name char(10));    create table tea(id int primary key auto_increment,name char(10));    create table tsr(id int primary key auto_increment,t_id int,s_id int,    foreign key(s_id) references stu(id),    foreign key(s_id) references stu(id));    insert into stu values(null,"張三"),(null,"李李四");    insert into tea values(null,"egon"),(null,"wer");    insert into tsr values(null,1,1),(null,1,2),(null,2,2);    select *from stu join tea join tsr    on stu.id = tsr.s_id and tea.id = tsr.t_id    where tea.name = "egon";    多表查詢套路        1.把全部表都連起來        2.加上鍊接條件        3.若是有別的過濾條件 加上where5.子查詢    子查詢是將一個查詢語句嵌套在另外一個查詢語句中。(內層查詢)        #2:內層查詢語句的查詢結果,能夠爲外層查詢語句提供查詢條件。        #3:子查詢中能夠包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字        #4:還能夠包含比較運算符:= 、 !=、> 、<等    何時使用子查詢        當一次查詢沒法獲得想要結果時  須要屢次查詢    子查詢原理,解決問題的思路        是把一個複雜的問題 拆分爲多個簡單的問題        是把一個複雜的查詢 拆分爲多個簡單的查詢    給你部門的的名稱    查部門有哪些人?        第一步查到部門的id        第二部 拿着id去員工表查詢    select *from dept join emp on dept.id = emp.dept_id;    select *from emp join    # 使用子查詢 獲得 每一個部門的id 以及部門的 最高工資  造成一個虛擬表 把原始表和 虛擬錶鏈接在一塊兒    (select dept_id,max(salary)as m from emp group by dept_id) as t1    # 若是這我的的部門編號 等於 虛擬表中的部門編號     on emp.dept_id = t1.dept_id     and     # 而且 若是這我的的工資 等於 虛擬表中的最高工資  就是你要找的人     emp.salary = t1.m;    create table emp (id int,name char(10),sex char,age int,dept_id int,job    char(10),salary double);    insert into emp values    (1,"劉備","男",26,1,"總監",5800),    (2,"張⻜飛","男",24,1,"員⼯工",3000),    (3,"關⽻羽","男",30,1,"員⼯工",4000),    (4,"孫權","男",25,2,"總監",6000),    (5,"周瑜","男",22,2,"員⼯工",5000),    (6,"⼩小喬","女",31,2,"員⼯工",4000),    (7,"曹操","男",19,3,"總監",10000),    (8,"司⻢馬懿","男",24,3,"員⼯工",6000);    select emp.name from emp inner join dep on emp.dep_id = dep.id where dep.name="技術";    select name from emp where dep_id =    (select id from dep where name="技術");1 帶IN關鍵字的子查詢    大多數子查詢均可以被鏈接查詢代替    in (1,2)    #查詢平均年齡在25歲以上的部門名        select name from dep where id in        (select dep_id from emp group by dep_id having avg(age) > 25);2 帶比較運算符的子查詢    select dep.name from emp inner join dep on emp.dep_id = dep.id                group by dep.name                having avg(age) > 25;3 帶EXISTS關鍵字的子查詢    EXISTS關字鍵字表示存在。在使用EXISTS關鍵字時,內層查詢語句不返回查詢的記錄。    而是返回一個真假值。True或False    當返回True時,外層查詢語句將進行查詢;當返回值爲False時,外層查詢語句不進行查詢    #查看不足2人的部門名(子查詢獲得的是有人的部門id)        select * from emp where exists (            select id from dep where id > 3        );    #查詢每一個部門最新入職的那位員工        select t1.id,t1.name,t1.post,t1.hire_date,t2.post,t2.max_date 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        ;
相關文章
相關標籤/搜索