濮阳杆衣贸易有限公司

主頁 > 知識(shí)庫 > MySQL入門(三) 數(shù)據(jù)庫表的查詢操作【重要】

MySQL入門(三) 數(shù)據(jù)庫表的查詢操作【重要】

熱門標(biāo)簽:深圳 外呼系統(tǒng)從哪買 商家地圖標(biāo)注哪個(gè)好 陜西400電話如何申請(qǐng) 德惠市地圖標(biāo)注 地圖標(biāo)注賺錢真假 合肥營(yíng)銷外呼系統(tǒng)收費(fèi) 遵義地圖標(biāo)注app 承德電腦地圖標(biāo)注

序言

 1、MySQL表操作(創(chuàng)建表,查詢表結(jié)構(gòu),更改表字段等),

 2、MySQL的數(shù)據(jù)類型(CHAR、VARCHAR、BLOB,等),

 本節(jié)比較重要,對(duì)數(shù)據(jù)表數(shù)據(jù)進(jìn)行查詢操作,其中可能大家不熟悉的就對(duì)于INNER JOIN(內(nèi)連接)、LEFT JOIN(左連接)、RIGHT JOIN(右連接)等一些復(fù)雜查詢。 通過本節(jié)的學(xué)習(xí),可以讓你知道這些基本的復(fù)雜查詢是怎么實(shí)現(xiàn)的,但是建議還是需要多動(dòng)手去敲,雖然理解了什么是內(nèi)連接等,但是從理解到學(xué)會(huì),是完全不一樣的感覺。

   --WH

一、單表查詢

      1.1、查詢所有字段

      1.2、查詢指定字段

      1.3、查詢指定記錄

      1.4、帶IN關(guān)鍵字的查詢

      1.5、帶BETWEEN AND 的范圍查詢

      1.6、帶LIKE的字符匹配查詢

      1.7、查詢空值

      1.8、帶AND的多條件查詢

      1.9、帶OR的多條件查詢

      1.10、關(guān)鍵字DISTINCT(查詢結(jié)果不重復(fù))

      1.11、對(duì)查詢結(jié)果排序

      1.12、分組查詢(GROUP BY)

      1.13、使用LIMIT限制查詢結(jié)果的數(shù)量

   集合函數(shù)查詢

      1.14、COUNT()函數(shù)

      1.15、SUM()函數(shù)

      1.16、AVG()函數(shù)

      1.17、MAX()函數(shù)

      1.18、MIN()函數(shù)    

二、多表查詢

   小知識(shí)

      為表取別名

      為字段取別名

   基于兩張表 

      2.1、普通雙表連接查詢

      2.2、內(nèi)連接查詢

      2.3、外連接查詢

2.3.1、左外連接查詢

2.3.2、右外連接查詢

      2.4、復(fù)合條件連接查詢

   子查詢

      2.5、帶ANY、SOME關(guān)鍵字的子查詢

      2.6、帶ALL關(guān)鍵字的子查詢

      2.7、帶EXISTS關(guān)鍵字的子查詢

      2.8、帶IN關(guān)鍵字的子查詢

      2.9、帶比較運(yùn)算符的子查詢

    

   合并結(jié)果查詢

      2.10、UNION[ALL]的使用

三、使用正則表達(dá)式查詢

      3.1、查詢以特定字符或字符串開頭的記錄

      3.2、查詢以特定字符或字符串結(jié)尾的記錄

      3.3、用符號(hào)"."來替代字符串中的任意一個(gè)字符

      3.4、使用"*"和"+"來匹配多個(gè)字符

      3.5、匹配指定字符串

      3.6、匹配指定字符中的任意一個(gè)

      3.7、匹配指定字符以外的字符

      3.8、使用{n,}或者{n,m}來指定字符串連續(xù)出現(xiàn)的次數(shù)

四、綜合案例 練習(xí)數(shù)據(jù)表查詢操作

      4.1、搭建環(huán)境

 省略

      4.2、查詢操作

 省略

      4.3、在已經(jīng)創(chuàng)建好的employee表中進(jìn)行如下操作

4.3.1、計(jì)算所有女員工(F)的年齡

4.3.2、使用LIMIT查詢從第3條記錄開始到第六條記錄

4.3.3、查詢銷售人員(SALSEMAN)的最低工資

4.3.4、查詢名字以字母N或者S結(jié)尾的記錄

4.3.5、查詢?cè)贐eiJing工作的員工的姓名和職務(wù)

4.3.6、使用左連接方式查詢employee和dept表

4.3.7、查詢所有2001~2005年入職的員工的信息,查詢部門編號(hào)為20和30的員工信息并使用UNION合并兩個(gè)查詢結(jié)果

4.3.8、使用LIKE查詢員工姓名中包含字母a的記錄

4.3.9、使用REGEXP查詢員工姓名中包含T、C或者M(jìn) 3個(gè)字母中任意1個(gè)的記錄

  想直接做題的,跳過講解,直接到練習(xí)區(qū)。

      這張講解的目錄就是想上面這樣,可以直接看自己感興趣的部分,而不用從最基礎(chǔ)的看起,接下來就一步步實(shí)現(xiàn)這上面龐大的工作量了。

一、單表查詢

      創(chuàng)建查詢環(huán)境

CREATE TABLE fruits(

  f_id CHAR(10) NOT NULL,

  s_id INT NOT NULL,

  f_name char(255) NOT NULL,

  f_price DECIMAL(8,2) NOT NULL,

  PRIMARY KEY(f_id)

);

解釋:

   f_id:主鍵 使用的是CHAR類型的字符來代表主鍵

   s_id:這個(gè)其實(shí)是批發(fā)商的編號(hào),也就是代表該水果是從哪個(gè)批發(fā)商那里過來的,寫這個(gè)字段的目的是為了方便后面擴(kuò)增表。

   f_name:水果的名字

   f_price:水果的價(jià)格,使用的是DECIMAL這個(gè)數(shù)據(jù)類型,如果不清楚這個(gè)類型去查看一下上面一篇講解數(shù)據(jù)類型的文章。

       添加數(shù)據(jù)。

INSERT INTO fruits(f_id,s_id,f_name,f_price) VALUES

   ('a1' , 101 , 'apple' , 5.2),

   ('b1' , 101 , 'blackberry' , 10.2),

   ('bs1' , 102 , 'orange' , 11.2),

   ('bs2' , 105 , 'melon' , 8.2),

   ('t1' , 102 , 'banana' , 10.3),

   ('t2' , 102 , 'grape' , 5.3),

   ('o2' , 103 , 'coconut' , 9.2),

   ('c0' , 101 , 'cherry' , 3.2),

   ('a2' , 103 , 'apricot' , 2.2),

   ('l2' , 104 , 'lemon' , 6.4),

   ('b2' , 104 , 'berry' , 7.6),

   ('m1' , 106, 'mango' , 15.6),

   ('m2' , 105 , 'xbabay' , 2.6),

   ('t4' , 107, 'xbababa' , 3.6),

   ('m3' , 105 , 'xxtt' , 11.6),

   ('b5' , 107, 'xxxx' , 3.6 );

      blackberry:黑莓  melon:甜瓜  grape:葡萄  coconut:椰子  cherry:櫻桃  apricot:杏子  berry:漿果  mango:芒果  后面幾個(gè)xbabay都是為了測(cè)試所編寫的,沒有實(shí)際意義。

      注意:在復(fù)制我的代碼到cmd窗口時(shí),應(yīng)注意語句之間不能有空格,不然會(huì)報(bào)錯(cuò),我這里是為了使你們觀看更清楚,所以每行前面度加有空格,

      1.1、查詢所有字段

 SELECT * FROM fruits;

  

   解釋:* 代表所有字段,也就是從表中將所有字段下面的記錄度查詢出來

      1.2、查詢指定字段

   查詢f_name 和 f_price 字段的記錄

   SELECT f_name, f_price FROM fruits;

  

      1.3、查詢指定記錄

   指定記錄:也就是按條件進(jìn)行查詢,將滿足一定條件的記錄給查詢出來,使用WHERE關(guān)鍵字

   SELECT * FROM fruits WHERE f_name = 'apple';  //將名為apple的記錄的所有信息度查詢出來

  

   SELECT * FROM fruits WHERE f_price > 15;    //將價(jià)格大于15的記錄的所有字段  查詢出來

  

      1.4、帶IN關(guān)鍵字的查詢

   IN關(guān)鍵字:IN(xx,yy,...) 滿足條件范圍內(nèi)的一個(gè)值即為匹配項(xiàng)

   SELECT * FROM fruits WHERE f_name IN('apple','orange');

  

   SELECT * FROM fruits WHERE s_id IN(101, 105); //s_id 為101 或者 105 的記錄

  

   SELECT * FROM fruits WHERE s_id NOT IN(101,105); //s_id 不為101或者105的記錄

  

   

      1.5、帶BETWEEN AND 的范圍查詢

   BETWEEN ... AND ... : 在...到...范圍內(nèi)的值即為匹配項(xiàng),

   SELECT * FROM fruits WHERE f_price BETWEEN 5 AND 15;  //f_price 在5到15之間,包括5和15。

  

   SELECT * FROM fruits WHERE f_price NOT BETWEEN 5 AND 15;  //f_price 不在5到15之間。

  

    

      1.6、帶LIKE的字符匹配查詢

    LIKE: 相當(dāng)于模糊查詢,和LIKE一起使用的通配符有 "%"、"_"

        "%":作用是能匹配任意長(zhǎng)度的字符。

        "_":只能匹配任意一個(gè)字符

    SELECT * FROM fruits WHERE f_name LIKE 'b%';  //f_name以b字母開頭的所有記錄

  

    SELECT * FROM fruits WHERE f_name LIKE 'b%y';  //f_name以b字母開頭,y字母結(jié)尾的所有記錄

  

    SELECT * FROM fruits WHERE f_name LIKE '____y';   //此處有四個(gè)_,說明要查詢以y字母結(jié)尾并且y之前只有四個(gè)字符的記錄

  

    總結(jié):'%'和'_'可以在任意位置使用,只需要記住%能夠表示任意個(gè)字符,_只能表示一個(gè)任意字符

  

      1.7、查詢空值

    空值不是指為空字符串""或者0,一般表示數(shù)據(jù)未知或者在以后在添加數(shù)據(jù),也就是在添加數(shù)據(jù)時(shí),其字段上默認(rèn)為NULL,也就是說,如果該字段上不插入任何值,就為NULL。此時(shí)就可以查詢出來。

    SELECT * FROM 表名 WHERE 字段名 IS NULL;  //查詢字段名是NULL的記錄

    SELECT * FROM 表名 WHERE 字段名 IS NOT NULL;  //查詢字段名不是NULL的記錄

    這里由于沒有合適的數(shù)據(jù),就不自己在創(chuàng)建表,添加數(shù)據(jù),然后來測(cè)試這條語句了,很簡(jiǎn)單,看一下就應(yīng)該懂了

      1.8、帶AND的多條件查詢

    AND: 相當(dāng)于"邏輯與",也就是說要同時(shí)滿足條件才算匹配

    SELECT * FROM fruits WHERE s_id = 101 AND f_price > 5;  //同時(shí)滿足s_id = 101、f_price >5 這兩個(gè)條件才算匹配。

    

      1.9、帶OR的多條件查詢

    OR: 相當(dāng)于"邏輯或",也就是說只要滿足其中一個(gè)條件,就算匹配上了,跟IN關(guān)鍵字效果差不多

    SELECT * FROM fruits WHERE s_id = 101 OR f_price > 10;  //s_id =101 或者 f_price >10 ,只要符合其中一個(gè)條件,就算匹配

    

     可以看到,查詢出來的記錄,f_price有低于10的,那么其肯定s_id=101,s_id不等于101的,其f_price肯定大于10,這就說明了OR的效果。只要滿足其中一個(gè)條件,就算匹配。

      1.10、關(guān)鍵字DISTINCT(查詢結(jié)果不重復(fù))

     SELECT s_id FROM fruits;  //查詢所有的s_id,會(huì)出現(xiàn)很多重復(fù)的值。

        

     使用DISTINCT就能消除重復(fù)的值

     SELECT DISTINCT s_id FROM fruits;

        

     將重復(fù)的值刪除后,就只留下7條記錄了。

       

      1.11、對(duì)查詢結(jié)果排序(ORDER BY)

     看上面輸出的值沒順序,可以給他們進(jìn)行排序。使用關(guān)鍵字 ORDER BY,有兩個(gè)值供選擇 DESC 降序 、 ASC 升序(默認(rèn)值)

     SELECT DISTINCT s_id FROM fruits ORDER BY s_id;    //默認(rèn)就是升序,

        

     SELECT DISTINCT s_id FROM fruits ORDER BY s_id DESC;  //使用降序,也就是從高到底排列

       

      1.12、分組查詢(GROUP BY)

     分組查詢很多人不知道什么意思,一開始我也是很蒙圈的,所以沒關(guān)系,一起來看看。

     分組查詢就是將相同的東西分到一個(gè)組里面去,現(xiàn)實(shí)生活中舉個(gè)例子,廁所分男女,這也是一個(gè)分組的應(yīng)用,在還沒有分男女廁所前,大家度共用廁所,后面通過分男女性別,男的跟男的分為一組,女的和女的分為一組,就這樣分為了男女廁所了。這就是分組的意思, 在上面對(duì)s_id進(jìn)行查詢的時(shí)候,發(fā)現(xiàn)很多重復(fù)的值,我們也就可以對(duì)它進(jìn)行分組,將相同的值分為一組,

     SELECT s_id FROM fruits GROUP BY s_id;  //將s_id進(jìn)行分組,有實(shí)際意義,按批發(fā)商進(jìn)行分組,從101批發(fā)商這里拿的水果度會(huì)放在101這個(gè)組中

       

     解釋:將s_id分組后,就沒有重復(fù)的值了,因?yàn)橹貜?fù)的度被分到一個(gè)組中去了,現(xiàn)在在來看看每個(gè)組中有多少個(gè)值

     SELECT s_id, COUNT(f_name), GROUP_CONCAT(f_name) FROM fruits GROUP BY s_id;

        

     解釋:

       COUNT():這個(gè)是下面要講解到的一個(gè)函數(shù),作用就是計(jì)算有多少條記錄, 

       GROUP_CONCAT(): 將分組中的各個(gè)字段的值顯示出來 

     SELECT s_id, COUNT(f_name), GROUP_CONCAT(f_name), GROUP_CONCAT(f_price) FROM fruits GROUP BY s_id;         

        

     分組之后還可以進(jìn)行條件過濾,將不想要的分組丟棄,使用關(guān)鍵字 HAVING

     SELECT s_id,COUNT(f_name),GROUP_CONCAT(f_name) FROM fruits GROUP BY s_id HAVING COUNT(f_name) > 1;//他能夠過s_id分組,然后過濾出水果種類大于1的分組信息。

        

總結(jié):

        知道GROUP BY的意義,并且會(huì)使用HAVING對(duì)分組進(jìn)行過濾, HAVING和WHERE都是進(jìn)行條件過濾的,區(qū)別就在于 WHERE 是在分組之前進(jìn)行過濾,而HAVING是在分組之后進(jìn)行條件過濾。

      1.13、使用LIMIT限制查詢結(jié)果的數(shù)量  

     LIMIT[位置偏移量] 行數(shù) 通過LIMIT可以選擇數(shù)據(jù)庫表中的任意行數(shù),也就是不用從第一條記錄開始遍歷,可以直接拿到 第5條到第10條的記錄,也可以直接拿到第12到第15條的記錄。 具體看下面例子

     SELECT * FROM fruits LIMIT 4;  //沒有寫位置偏移量,默認(rèn)就是0,也就是從第一條開始,往后取4條數(shù)據(jù),也就是取了第一條數(shù)據(jù)到第4條的數(shù)據(jù)。

       

     SELECT * FROM fruits LIMIT 4,3;  //從第5條數(shù)據(jù)開始,往后取3條數(shù)據(jù),也就是從第5條到第8條

       

     注意:LIMIT的第一個(gè)參數(shù)不寫默認(rèn)就是0,也就是說,第一條記錄的索引是0,從0開始的,第二個(gè)參數(shù)的意思是取多少行的記錄,需要這兩個(gè)才能確定一個(gè)取記錄的范圍

   集合函數(shù)查詢

      1.14、COUNT()函數(shù)

     這個(gè)函數(shù)在上面其實(shí)用過,作用是統(tǒng)計(jì)數(shù)據(jù)表中包含的記錄行的總數(shù),或者根據(jù)查詢結(jié)果返回列中包含的數(shù)據(jù)行數(shù),

       COUNT(*):計(jì)算表中的總的行數(shù),不管某列有數(shù)值或者為空值,因?yàn)?就是代表查詢表中所有的數(shù)據(jù)行

       COUNT(字段名):計(jì)算該字段名下總的行數(shù),計(jì)算時(shí)會(huì)忽略空值的行,也就是NULL值的行。

     SELECT COUNT(*) FROM fruits;

        

     SELECT COUNT(f_name) FROM fruits;  //查詢fruits表中f_name字段名下有多少個(gè)行數(shù),

        

  沒有空值,所以計(jì)算出來的行數(shù)和總的記錄行數(shù)是一樣的。

      1.15、SUM()函數(shù)

     SUM()是一個(gè)求總和的函數(shù),返回指定列值的總和

     SELECT SUM(f_price) FROM fruits;  //這個(gè)沒有實(shí)際的意義,只是測(cè)試SUM()函數(shù)有求總和的能力

       

 如果有人覺得這個(gè)測(cè)試的不準(zhǔn),可以手動(dòng)去加一下所有的f_price。然后來進(jìn)行對(duì)比,反正我是信了。

      1.16、AVG()函數(shù)

    AVG()函數(shù)通過計(jì)算返回的行數(shù)和每一行數(shù)據(jù)的和,求的指定列數(shù)據(jù)的平均值(列數(shù)據(jù)指的就是字段名下的數(shù)據(jù),不要搞不清楚列和行,搞不清就對(duì)著一張表搞清楚哪個(gè)是列哪個(gè)是行),通俗點(diǎn)講,就是將計(jì)算得來的總之除以總的記錄數(shù),得出一個(gè)平均值,

     SELECT AVG(f_price) FROM fruits;  

       

  就相當(dāng)于  116/16 = 7.25

      1.17、MAX()函數(shù)

     MAX()返回指定列中的最大值

      SELECT MAX(f_price) FROM fruits;

        

      1.18、MIN()函數(shù)    

    MIN()返回查詢列中的最小值

     SELECT MIN(f_price) FROM fruits;

       

二、多表查詢

   小知識(shí)

      為表取別名

 因?yàn)槭菍?duì)兩張表進(jìn)行查詢了,那么每次寫表名的話就有點(diǎn)麻煩,所以用一個(gè)簡(jiǎn)單別名來代表表名

  格式:表名 AS 別名

  在下面的例子中會(huì)用的到,到時(shí)候不要不認(rèn)識(shí)

      為字段取別名

 給字段名取別名的原因是有些字段名是為了顯示更加清楚,比如

       SELECT f_price AS '價(jià)格' FROM fruits;

        

      語句執(zhí)行順序問題

   一、sql執(zhí)行順序 、

     (1)from   
     (2) on
     (3) join
     (4) where
     (5)group by
     (6) avg,sum....
     (7)having
     (8) select
     (9) distinct
     (10) order by

 也就是說,我們每次執(zhí)行的SQL語句,都是從FROM開始的。

   基于兩張表 

     搭建查詢環(huán)境,前面已經(jīng)有一張表了,現(xiàn)在在增加一張suppliers(供應(yīng)商)表和前面哪個(gè)fruits表創(chuàng)建練習(xí),也就是說 讓fruits中s_id字段值指向suppliers的主鍵值,創(chuàng)建一個(gè)外鍵約束關(guān)系。

        CREATE TABLE suppliers  

        (

 s_id INT NOT NULL,

 s_name CHAR(50) NOT NULL,

 s_city CHAR(50) NULL,

 s_zip CHAR(10) NULL,

 s_call CHAR(50) NOT NULL,

 PRIMARY KEY(s_id)

        );

        其實(shí)這里并沒有達(dá)到真正的外鍵約束關(guān)系,只是模擬,讓fruits中的s_id中的值 能匹配到 suppliers 中的主鍵值,通過手動(dòng)添加這種數(shù)據(jù),來達(dá)到這種關(guān)系,反正是死數(shù)據(jù),也不在添加別的數(shù)據(jù),就不用建立外鍵約束關(guān)系了,這里要搞清楚

        INSERT INTO suppliers(s_id,s_name,s_city,s_zip,s_call)

        VALUES

        (101,'Supplies A','Tianjin','400000','18075'),

        (102,'Supplies B','Chongqing','400000','44333'),

        (103,'Supplies C','Shanghai','400000','90046'),

        (104,'Supplies D','Zhongshan','400000','11111'),

        (105,'Supplies E','Taiyuang','400000','22222'),

        (106,'Supplies F','Beijing','400000','45678'),

        (107,'Supplies G','Zhengzhou','400000','33332');

  

      2.1、普通雙表連接查詢

 問題:查詢水果的批發(fā)商編號(hào),批發(fā)商名字,水果名稱,水果價(jià)格

    分析:看下要求,就知道要查詢兩張表,如果需要查詢兩張表,那么兩張表的關(guān)系必定是外鍵關(guān)系,或者類似于外鍵關(guān)系(類似于也就是說兩張表并沒有真正加外鍵約束,但是其特點(diǎn)和外鍵是一樣的,就像上面我們手動(dòng)創(chuàng)建的兩張表一樣,雖然沒有設(shè)置外鍵關(guān)聯(lián)關(guān)系,但是其特性跟外鍵關(guān)系是一樣的。)

  SELECT s.s_id,s.s_name,f.f_name,f.f_price FROM fruits AS f, suppliers AS s WHERE f.s_id = s.s_id;

    

     解釋:這里使用了表別名,并且這里是連接兩張表的關(guān)系是在于 fruits中的s_id 等于 suppliers中的s_id。 這個(gè)大家度能理解把,也就是水果中記錄了批發(fā)商的編號(hào),通過該編號(hào)就能在suppliers表中找到對(duì)應(yīng)的批發(fā)商的詳細(xì)信息,就這樣,兩張表就聯(lián)系起來了。

     注意:第一個(gè)執(zhí)行的是FROM,所以上面為表取別名,在語句的任何地方的可以使用。

      2.2、內(nèi)連接查詢

     知道了上面兩張表基本的連接查詢后,內(nèi)連接查詢就很簡(jiǎn)單了,因?yàn)閮?nèi)連接跟上面的作用是一樣的,唯一的區(qū)別就是語法的不一樣

      格式:表名 INNER JOIN 表名 ON 連接條件

      問題:查詢水果的批發(fā)商編號(hào),批發(fā)商名字,水果名稱,水果價(jià)格

        SELECT s.s_id,s.s_name,f.f_name,f.f_price

        FROM fruits AS f INNER JOIN suppliers AS s

        ON f.s_id = s.s_id;

     不知道這樣寫sql語句會(huì)不會(huì)讓你們看的更清楚

  

     

   還需要知道一個(gè)特殊一點(diǎn)的東西,那就是自連接查詢,什么是自連接查詢?就是涉及到的兩張表都是同一張表。

   問題:查詢供應(yīng)f_id='a1'的水果供應(yīng)商提供的其他水果種類?

     SELECT f2.f_id,f2.f_name

     FROM fruits AS f1 INNER JOIN fruits AS f2

     ON f1.s_id = f2.s_id AND f1.f_id = 'a1';

    

     解釋:把fruits表分開看成是兩張完全一樣的表,在f1表中找到f_id='a1'的s_id,然后到f2這張表中去查找和該s_id相等的記錄,也就查詢出來了問題所需要的結(jié)果。還有另一種方法,不用內(nèi)連接查詢,通過子查詢也可以做到,下面會(huì)講解,這里先給出答案,到時(shí)可以回過頭來看看這個(gè)題。

     SELECT f_id,f_name

     FROM fruits

     WHERE s_id = (SELECT s_id FROM fruits WHERE f_id='a1');

    

     效果和內(nèi)連接是一樣的,其實(shí)原理度是一樣的,還是借助的兩張表,只是這個(gè)更容易讓人理解,可以通過這個(gè)來去理解上面那個(gè)自連接查詢。

      2.3、外連接查詢

     內(nèi)連接是將符合查詢條件(符合連接條件)的行返回,也就是相關(guān)聯(lián)的行就返回。

      外連接除了返回相關(guān)聯(lián)的行之外,將沒有關(guān)聯(lián)的行也會(huì)顯示出來。

      為什么需要將不沒關(guān)聯(lián)的行也顯示出來呢?這就要根據(jù)不同的業(yè)務(wù)需求了,就比如,order和customers,顧客可以有訂單也可以沒訂單,現(xiàn)在需要知道所有顧客的下單情況,而我們不能夠只查詢出有訂單的用戶,而把沒訂單的用戶丟在一邊不顯示,這個(gè)就跟我們的業(yè)務(wù)需求不相符了,有人說,既然知道了有訂單的顧客,通過單表查詢出來不包含這些有訂單顧客,不就能達(dá)到我們的要求嗎,這樣是可以,但是很麻煩,如何能夠?qū)⑵湟黄痫@示并且不那么麻煩呢?為了解決這個(gè)問題,就有了外連接查詢這個(gè)東西了。

2.3.1、左外連接查詢

      格式: 表名 LEFT JOIN 表名 ON 條件; 返回包括左表中的所有記錄和右表中連接字段相等的記錄,通俗點(diǎn)講,就是除了顯示相關(guān)聯(lián)的行,還會(huì)將左表中的所有記錄行度顯示出來。用例子來展示一下所說效果把。

      由于上面我們所用到的fruits和suppliers中的記錄都是設(shè)計(jì)好的,并沒有哪個(gè)供應(yīng)商沒有提供水果,現(xiàn)在為了體現(xiàn)左外連接的效果,在suppliers中增加兩條記錄,fruits中并沒有對(duì)應(yīng)這兩條記錄得水果信息,

      INSERT INTO suppliers VALUES(108,'suppliers T','Jiangxi','33333','11111');

      INSERT INTO suppliers VALUES(109,'suppliers Y','Jiangxi','22222','44444');

 

     SELECT s.s_id,s.s_name,f.f_id,f.f_name

     FROM suppliers AS s LEFT JOIN fruits AS f

     ON s.s_id = f.s_id;

 

解釋:

   suppliers表是在LEFT JOIN的左邊,所以將其中所有記錄度顯示出來了,有關(guān)聯(lián)項(xiàng)的,也有沒有關(guān)聯(lián)項(xiàng)的。這就是左外連接的意思,將左邊的表所有記錄都顯示出來(前提是按照我們所需要的字段,也就是SELECT 后面所選擇的字段)。如果將suppliers表放LEFT JOIN的右邊,那么就不會(huì)在顯示108和109這兩條記錄了。來看看

     SELECT s.s_id,s.s_name,f.f_id,f.f_name

     FROM fruits AS f LEFT JOIN suppliers AS s

     ON s.s_id = f.s_id;

 

       

2.3.2、右外連接查詢

      格式: 表名 RIGHT JOIN 表名 ON 條件 返回包括右表中的所有記錄和右表中連接字段相等的記錄

      其實(shí)跟左外連接差不多,就是將右邊的表給全部顯示出來

       SELECT s.s_id,s.s_name,f.f_id,f.f_name

       FROM fruits AS f RIGHT JOIN suppliers AS s

       ON s.s_id = f.s_id;     //這條語句出來的結(jié)果是跟上面左外連接一樣,就是調(diào)換了一下位置,其實(shí)效果還是一樣的。

 

          

     注意:

       LEFT JOIN 和 RIGHT JOIN這只是一種寫法,其中還有另一種寫法 LEFT OUTER JOIN 和 RIGHT OUTER JOIN .

       一般寫這種復(fù)雜查詢的時(shí)候,寫sql語句的順序應(yīng)該是先從FROM  

      2.4、復(fù)合條件連接查詢

     在連接查詢(內(nèi)連接、外連接)的過程中,通過添加過濾條件,限制查詢的結(jié)果,使查詢的結(jié)果更加準(zhǔn)確,通俗點(diǎn)講,就是將連接查詢時(shí)的條件更加細(xì)化。

      問題一:在fruits和suppliers表中使用INNER JOIN語法查詢suppliers表中s_id為107的供應(yīng)商的供貨信息?

SELECT s.s_id,s.s_name,f.f_id,f.f_name

FROM suppliers AS s INNER JOIN fruits AS f

ON s.s_id = f.s_id AND s.s_id = 107;

 

     問題二:在fruits表和suppliers表之間,使用INNER JOIN語法進(jìn)行內(nèi)連接查詢,并對(duì)查詢結(jié)果進(jìn)行排序

SELECT s.s_id,s.s_name,f.f_id,f.f_name

FROM suppliers AS s INNER JOIN fruits AS f

ON s.s_id = f.s_id

ORDER BY f.s_id;        //對(duì)f.s_id進(jìn)行升序。默認(rèn)的是ASC,所以不用寫。

 

      對(duì)f.s_id進(jìn)行排序其實(shí)也就是對(duì)s.s_id進(jìn)行排序,效果是一樣的,因?yàn)闂l件就是f.s_id=s.s_id。

   子查詢

        子查詢,將查詢一張表得到的結(jié)果來充當(dāng)另一個(gè)查詢的條件,這樣嵌套的查詢就稱為子查詢

      2.5、帶ANY、SOME關(guān)鍵字的子查詢     

  搭建環(huán)境

      CREATE TABLE tb11 (num1 INT NOT NULL);

      CREATE TABLE tb12 (num2 INT NOT NULL);

      INSERT INTO tb11 VALUES(1),(5),(13),(27);

      INSERT INTO tb12 VALUES(6),(14),(11),(20);

  ANY關(guān)鍵字接在一個(gè)比較操作符的后面,表示若與子查詢返回的任何值比較為TRUE,則返回TRUE,通俗點(diǎn)講,只要滿足任意一個(gè)條件,就返回TRUE。

     SELECT num1 FROM tb11 WHERE num1 > ANY(SELECT num2 FROM tb12);//這里就是將在tb12表中查詢的結(jié)果放在前一個(gè)查詢語句中充當(dāng)條件參數(shù)。只要num1大于其結(jié)果中的任意一個(gè)數(shù),那么就算匹配。

   SOME關(guān)鍵字和ANY關(guān)鍵字的用法一樣,作用也相同,這里不做多講解了。

      2.6、帶ALL關(guān)鍵字的子查詢

   使用ALL時(shí)表示需要同時(shí)滿足所有條件。

       SELECT num1 FROM tb11 WHERE num1 > ALL(SELECT num2 FROM tb12);  //num1需要大于所有的查詢結(jié)果才算匹配

 

      2.7、帶EXISTS關(guān)鍵字的子查詢

   EXISTS關(guān)鍵字后面的參數(shù)是任意一個(gè)子查詢,如果子查詢有返回記錄行,則為TRUE,外層查詢語句將會(huì)進(jìn)行查詢,如果子查詢沒有返回任何記錄行,則為FALSE,外層查詢語句將不會(huì)進(jìn)行查詢。

       SLEECT * FROM tb11 WHERE EXISTS(SELECT * FROM tb12 WHERE num2 = 3);  //查詢tb12中有沒有num2=3的記錄,有的話則會(huì)將tb11的所有記錄查詢出來,沒有的話,不做查詢

 

      2.8、帶IN關(guān)鍵字的子查詢

    這個(gè)IN關(guān)鍵字的作用跟上面單表查詢的IN是一樣的,不過這里IN中的參數(shù)放的是一個(gè)子查詢語句。

       SELECT s_id,f_id,f_name

       FROM fruits

       WHERE s_id IN(SELECT s_id FROM suppliers WHERE s_id = 107);

 

      2.9、帶比較運(yùn)算符的子查詢

    除了使用關(guān)鍵字ALL、ANY、SOME等之外,還可以使用普通的比較運(yùn)算符。來進(jìn)行比較。比如我們上面講解內(nèi)連接查詢的時(shí)候,就用過子查詢語句,并且還是用的=這個(gè)比較運(yùn)算符,這里就不做多解釋了,可以往上面看一下 

    

   合并結(jié)果查詢

        利用UNION關(guān)鍵字,可以將查詢出的結(jié)果合并到一張結(jié)果集中,也就是通過UNION關(guān)鍵字將多條SELECT語句連接起來,注意,合并結(jié)果集,只是增加了表中的記錄,并不是將表中的字段增加,僅僅是將記錄行合并到一起。其顯示的字段應(yīng)該是相同的,不然不能合并。

      2.10、UNION[ALL]的使用

        UNION:不使用關(guān)鍵字ALL,執(zhí)行的時(shí)候會(huì)刪除重復(fù)的記錄,所有返回的行度是唯一的,

         UNION ALL:不刪除重復(fù)航也不對(duì)結(jié)果進(jìn)行自動(dòng)排序。

        格式:

   SELECT 字段名,... FROM 表名

   UNION[ALL]

   SELECT 字段名,... FROM 表名

        問題一:查詢所有價(jià)格小于9的水果的信息,查詢s_id等于101個(gè)103所有水果的信息,使用UNION連接查詢結(jié)果

   SELECT s_id,f_name,f_price FROM fruits WHERE f_price 9

   UNION ALL

   SELECT s_id,f_name,f_price FROM fruits WHERE s_id = 101 OR s_id=103;

   解釋:顯示的字段都是s_id,f_name,f_price,只是將兩個(gè)的記錄行合并到一張表中。僅僅增加的是記錄行,而顯示的字段還是那三個(gè),沒有增加,

   

   使用UNION,而不用UNION ALL的話,重復(fù)的記錄就會(huì)被刪除掉。

 

三、使用正則表達(dá)式查詢

      這個(gè)非常簡(jiǎn)單,就是使用REGEXP關(guān)鍵字來指定正則表達(dá)式,畫一張表格,就能將下面所有的度覆蓋掉。

   

      3.1、查詢以特定字符或字符串開頭的記錄

   SELECT * FROM fruits WHERE f_name REGEXP '^b';    //以b開頭的記錄

    

   就講解這一個(gè),下面這些的形式跟這個(gè)一模一樣,唯一的差別就在正則表達(dá)式不一樣,一般使用這種模糊查詢,使用MySQL中的'_'和'%'就已經(jīng)足夠了。

      3.2、查詢以特定字符或字符串結(jié)尾的記錄

      3.3、用符號(hào)"."來替代字符串中的任意一個(gè)字符

      3.4、使用"*"和"+"來匹配多個(gè)字符

      3.5、匹配指定字符串

      3.6、匹配指定字符中的任意一個(gè)

      3.7、匹配指定字符以外的字符

      3.8、使用{n,}或者{n,m}來指定字符串連續(xù)出現(xiàn)的次數(shù)

四、綜合案例 練習(xí)數(shù)據(jù)表查詢操作

      4.1、搭建環(huán)境

        兩張表: employee(員工)表和dept(部門)表。

     CREATE TABLE dept

     (

       d_no INT NOT NULL PRIMARY KEY AUTO_INCREMENT,    //部門編號(hào)

       d_name VARCHAR(50),  //部門名稱

       d_location VARCHAR(100)//部門地址

     );

      CREATE TABLE employee

      (

       e_no INT NOT NULL PRIMARY KEY,    //員工編號(hào)

       e_name VARCHAR(100) NOT NULL,    //員工姓名

       e_gender CHAR(2) NOT NULL,      //員工性別

       dept_no INT NOT NULL,//部門編號(hào)

       e_job VARCHAR(100) NOT NULL,    //職位

       e_salary SMALLINT NOT NULL,     //薪水

       hireDate DATE,    //入職日期

       CONSTRAINT dno_fk FOREIGN KEY(dept_no) REFERENCES dept(d_no)

      );

表結(jié)構(gòu)

    

        插入數(shù)據(jù)

    INSERT INTO dept

    VALUES

       (10,'ACCOUNTING','ShangHai'),

       (20,'RESEARCH','BeiJing'),

       (30,'SALES','ShenZhen'),

       (40,'OPERATIONS','FuJian');

   單詞解釋:ACCOUNTING:會(huì)計(jì)部門  RESEARCH:研發(fā)部  SALES:銷售部  OPERATIONS:實(shí)踐部

   

    INSERT INTO employee

    VALUES

       (1001, 'SMITH' , 'm' , 20 , 'CLERK' , 800 , '2005-11-12'),

       (1002, 'ALLEN' , 'f' , 30 , 'SALESMAN' , 1600, '2003-05-12'),

       (1003, 'WARD' , 'f' , 30 , 'SALESMAN' , 1250, '2003-05-12'),

       (1004, 'JONES' , 'm' , 20 , 'MANAGER' , 2975, '1998-05-18'),

       (1005, 'MARTIN' , 'm' , 30 , 'SALESMAN' , 1250, '2001-06-12'),

       (1006, 'BLAKE' , 'f' , 30 , 'MANAGER' , 2850, '1997-02-15'),

       (1007, 'CLARK' , 'm' , 10 , 'MANAGER' , 2450, '2002-09-12'),

       (1008, 'SCOTT' , 'm' , 20 , 'ANALYST' , 3000, '2003-05-12'),

       (1009, 'KING' , 'f' , 10 , 'PRESIDENT' , 5000, '1995-01-01'),

       (1010, 'TURNER' , 'f' , 30 , 'SALESMAN' , 1500, '1997-10-12'),

       (1011, 'ANAMS' , 'm' , 20 , 'CLERK' , 1100, '1999-10-15'),

       (1012, 'JAMES' , 'f' , 30 , 'CLERK' , 950, '2008-06-15');

   單詞解釋:SALESMAN:銷售員  CLERK:普通職員  MANAGER:經(jīng)理  PRESIDENT:董事長(zhǎng)  ANALYST:分析師 m:male 男性  f:female 女性

    

      4.2、查詢操作     

4.2.1、在employee表中,查詢所有記錄的e_no,e_name和e_salary字段值

       SELECT e_no,e_name,e_salary FROM employee;

    

4.2.2、在employee表中,查詢dept_no等于10和20的所有記錄

       方式一:SELECT * FROM employee WHERE dept_no IN(10,20);

    

       方式二:SELECT * FROM employee WHERE dept_no = 10 OR dept_no = 20;

    

4.2.3、在employee表中,查詢工資范圍在800~2500之間的員工信息

       SELECT * FROM employee WHERE e_salary BETWEEN 800 AND 2500;

    

4.2.4、在employee表中,查詢部門編號(hào)為20的部門中的員工信息

       SELECT * FROM employee WHERE dept_no = 20;

    

4.2.5、在employee表中,查詢每個(gè)部門最高工資的員工信息

     分析:每個(gè)員工都可能處于不同的部門,要先找出每個(gè)部門中的所有員工,應(yīng)該想到分組,將相同部門的員工分為一組。然后在使用MAX()函數(shù)比較最大的salary。注意不要MAX(GROUP_CONCAT(e_salary)), 這樣寫就會(huì)報(bào)錯(cuò),GROUP_CONCAT(e_salary)是將分組中所有的e_salary顯示出來,我們直接MAX(e_salary)就會(huì)將該分組中所有的e_salary進(jìn)行比較,拿到最大的一份。

       SELECT e_no,e_name,MAX(e_salary) FROM employee GROUP BY dept_no;

      

       我嘗試過其他方法,但是最終還是要對(duì)在相同部門中的員工做比較,只有通過分組才能對(duì)相同部門中的員工做比較,如果不分組,那么將對(duì)全部的記錄進(jìn)行比較。

4.2.6、查詢員工BLAKE所在部門和部門所在地

     分析:看下題目就應(yīng)該知道是兩張表,也就應(yīng)該使用連接查詢,找出是用內(nèi)連接還是外連接,然后找出連接條件,

   方式一:SELECT d.d_no,d.d_name,d.d_location

        FROM employee AS e,dept AS d

        WHERE e.e_name = 'BLAKE' AND e.dept_no = d.d_no;

    

   方式二:SELECT d.d_no,d.d_name,d.d_location

        FROM employee AS e INNER JOIN dept AS d

        ON e.e_name = 'BLAKE' AND e.dept_no = d.d_no;

    

4.2.7、使用連接查詢,查詢所有員工的部門和部門信息

     分析:這個(gè)題跟上面哪個(gè)題差不多,使用內(nèi)連接

     SELECT e.e_no,e.e_name,d.d_no,d.d_name,d.d_location

     FROM employee AS e INNER JOIN dept AS d

     ON e.dept_no = d.d_no;

    

4.2.8、在employee中,計(jì)算每個(gè)部門各有多少員工

     分析:每個(gè)部門用分組

     SELECT COUNT(e.e_name)

     FROM employee AS e

     GROUP BY e.dept_no  

         

      注意:SUM()和COUNT()要分清楚,SUM()是計(jì)算數(shù)值總和的,COUNT()是計(jì)算總的記錄行數(shù)的。

4.2.9、在employee表中,計(jì)算不同類型職員的總工資數(shù)

     分析:對(duì)員工職位類型進(jìn)行分組

     SELECT e.e_job,SUM(e.e_salary)

     FROM employee AS e

     GROUP BY e.e_job;

      

4.2.10、在employee表中,計(jì)算不同部門的平均工資

     分析:對(duì)部門進(jìn)行分組

      SELECT e.dept_no,AVG(e.e_salary)

      FROM employee AS e

      GROUP BY e.dept_no;

      

4.2.11、在employee表中,查詢工資低于1500的員工信息

      SELECT * from employee WHERE e_salary 1500;

        

4.2.12、在employee表中,將查詢記錄先按部門編號(hào)由高到低排列,再按員工工資由高到低排列

      SELECT * FROM employee ORDER BY dept_no DESC,e_salary DESC;

      

4.2.13、在employee表中,查詢員工姓名以字母A或S開頭的員工信息

      方式一: SELECT * FROM employee WHERE e_name LIKE 'A%' OR e_name LIKE 'S%';

      

      方式二:SELECT * FROM employee WHERE e_name REGEXP '^A' OR e_name REGEXP '^S';

      

4.2.14、在employee表中,查詢到目前為止,工齡大于等于10年的員工信息

      方式一:SELECT * FROM employee WHERE (YEAR(NOW()) - YEAR(hireDate)) > 10;  

      

      方式二:SELECT * FROM employee WHERE (YEAR(CURDATE()) - YEAR(hireDate)) > 10; 

       

       解釋:記得我們前一節(jié)學(xué)的數(shù)據(jù)類型嗎,其中CURDATE()代表的是YYYY-MM-DD, NOW()代表的是YYYY-MM-DD HH:MM:SS,所以這里兩個(gè)度能用,只要將其截取為為YEAR,然后相減,就能得到相差幾年了。

      4.3、在已經(jīng)創(chuàng)建好的employee表中進(jìn)行如下操作

4.3.1、計(jì)算所有女員工(F)的年齡(從入職到現(xiàn)在的時(shí)間)

       SELECT e.e_name,e.e_gender,YEAR(CURDATE()) - YEAR(e.hireDate)

        FROM employee AS e

        WHERE e.e_gender = 'f';

      

4.3.2、使用LIMIT查詢從第3條記錄開始到第六條記錄

        SELECT * FROM employee LIMIT 2,3; 

      

4.3.3、查詢銷售人員(SALSEMAN)的最低工資

        SELECT MIN(e_salary)

         FROM employee

         WHERE e_job = 'SALESMAN'; 

        

4.3.4、查詢名字以字母N或者S結(jié)尾的記錄

        方式一:

   SELECT * FROM employee WHERE e_name LIKE '%N' OR e_name LIKE '%S'; 

        

        方式二:

   SELECT * FROM employee WHERE e_name REGEXP 'N$' OR e_name REGEXP 'S$';

        

4.3.5、查詢?cè)贐eiJing工作的員工的姓名和職務(wù)

       方式一:SELECT e_name,e_job FROM employee WHERE dept_no = (SELECT d_no FROM dept WHERE d_location = 'BeiJing');

        

       方式二:SELECT e.e_name, e.e_job FROM employee AS e,dept AS d WHERE e.dept_no = d.d_no AND d.d_location = 'BeiJing';

        

       方式三:SELECT e.e_name,e.e_job FROM employee AS e INNER JOIN dept AS d ON e.dept_no = d.d_no AND d.d_location = 'BeiJing';

        

4.3.6、使用左連接方式查詢employee和dept表

       SELECT * FROM employee LEFT JOIN dept ON employee.dept_no = dept.d_no;

        

4.3.7、查詢所有2001~2005年入職的員工的信息,查詢部門編號(hào)為20和30的員工信息并使用UNION合并兩個(gè)查詢結(jié)果

  SELECT * FROM employee WHERE YEAR(hireDate) BETWEEN 2001 AND 2005

   UNION

   SELECT * FROM employee WHERE dept_no IN(20,30);

        

4.3.8、使用LIKE查詢員工姓名中包含字母a的記錄

  SELECT * FROM employee WHERE e_name LIKE 'a%' OR e_name LIKE '%a' OR e_name LIKE '%a%'; 

           

4.3.9、使用REGEXP查詢員工姓名中包含T、C或者M(jìn) 3個(gè)字母中任意1個(gè)的記錄

  SELECT * FROM employee WHERE e_name REGEXP '[TCM]';

        

總結(jié):

      花了我一天多的時(shí)間寫這篇文章,收獲很大,總結(jié)以下幾點(diǎn)

      1、在寫復(fù)雜查詢的時(shí)候,也就是涉及到兩張表時(shí),先寫FROM,然后在寫別的,要知道SQL語句的執(zhí)行順序

      2、單表查詢不是很難,記住幾個(gè)特點(diǎn)的,LIKE、GROUP BY很重要。記住他的用法

      3、兩張表的查詢也就是內(nèi)連接、外連接,外連接包括左外連接和右外連接,理解了這幾個(gè),基本上就沒什么難處

      4、多練,把我寫的全部自己實(shí)現(xiàn)一遍,基本上你就能夠全部理解透徹了,并且在做題的過程中慢慢就會(huì)自己總結(jié)一些做題的經(jīng)驗(yàn)。

 希望能對(duì)大家有所幫助,如果有幫助,就請(qǐng)順手點(diǎn)個(gè)推薦把,哈哈?! ?/p>

您可能感興趣的文章:
  • MySQL入門(四) 數(shù)據(jù)表的數(shù)據(jù)插入、更新、刪除
  • MySQL入門(二) 數(shù)據(jù)庫數(shù)據(jù)類型詳解
  • MySQL入門(一) 數(shù)據(jù)表數(shù)據(jù)庫的基本操作
  • MySQL入門(五) MySQL中的索引詳講

標(biāo)簽:揚(yáng)州 貴州 新余 贛州 南陽 三門峽 商丘 巴中

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《MySQL入門(三) 數(shù)據(jù)庫表的查詢操作【重要】》,本文關(guān)鍵詞  MySQL,入門,三,數(shù)據(jù)庫,表,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《MySQL入門(三) 數(shù)據(jù)庫表的查詢操作【重要】》相關(guān)的同類信息!
  • 本頁收集關(guān)于MySQL入門(三) 數(shù)據(jù)庫表的查詢操作【重要】的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    永吉县| 无极县| 阳山县| 威远县| 合作市| 彰化县| 鹤壁市| 黑河市| 禄劝| 咸阳市| 化州市| 公主岭市| 温宿县| 剑阁县| 财经| 宁都县| 乌苏市| 垣曲县| 阿荣旗| 曲阳县| 池州市| 淮阳县| 隆安县| 北海市| 龙山县| 治县。| 日照市| 宁海县| 长春市| 遵化市| 平江县| 哈尔滨市| 城步| 昭平县| 万安县| 格尔木市| 乃东县| 开化县| 招远市| 蒲江县| 巧家县|