MySQL基礎(chǔ)教程2-DQL(select查詢)

  • 注意: 撰寫本文目的主要是為了給自己做一個備忘錄,如果你學(xué)過Mysql并且希望從本文中找到一些忘記的知識點,那么你可以閱讀本文章。由于文章內(nèi)講解并不是很多,因此此文章并不適合小白入門使用。

select查詢

序、簡單查詢事項

1.避免重復(fù)數(shù)據(jù)查詢

select distinct name from user;

2.實現(xiàn)數(shù)學(xué)運算數(shù)據(jù)查詢

select age*10 from user;

給運算過的數(shù)據(jù)設(shè)置顯示名稱:
select num*10 as salary from user;

3.條件查詢

單條件查詢:
select * from user where name='xqz';

多條件查詢:
select * from user where name='xqz' && age=19;

** 4.符合范圍的記錄查詢**

select name age
    from user 
        where age between 18 and 20

5.帶IS NULL關(guān)鍵字的空值查詢

空值數(shù)據(jù)查詢:
SELECT NAME AGE
    FROM USER
        WHERE AGE IS NULL;

非空值數(shù)據(jù)查詢:
... IS NOT NULL;

一、group分組與統(tǒng)計函數(shù)

理解: 根據(jù)某一指定屬性對前面select之后的運算進(jìn)行分組執(zhí)行
例如: select age,avg(id) from user group by age;
      解釋:分別求出各年齡(age)段的id平均值

本小節(jié)知識清單:

  • max()
  • count()
  • avg()
  • min()
  • sum()
  • round()
select max(age) from user;          /* 獲得所有用戶最大的年齡 */
select count(age) from user;        /* 獲得所有用戶的數(shù)量 */
select avg(age) from user;          /* 求出所有用戶的年齡平均值 */
select min(age) from user;          /* 獲得所有用戶最小的年齡 */
select sum(age) from user;          /* 求出所有用戶的年齡之和 */
select sum(id*age) from user;       /*求出所有用戶的 id*age 值的和*/

round()函數(shù)

1. round(x,d)  ,x指要處理的數(shù),d是指保留幾位小數(shù)
這里有個值得注意的地方是,d可以是負(fù)數(shù),這時是指定小數(shù)點左邊的d位整數(shù)位為0,同時小數(shù)位均為0;
2、round(x)  ,其實就是round(x,0),也就是默認(rèn)d為0;
下面是幾個實例
1. 查詢: select round(1123.26723,2);
     結(jié)果:1123.27
2、查詢: select round(1123.26723,1);
     結(jié)果: 1123.3
3、查詢: select round(1123.26723,0);
     結(jié)果:1123
4、查詢: select round(1123.26723,-1);
     結(jié)果: 1120
5、查詢: select round(1123.26723,-2);
     結(jié)果:1100
6、查詢: select round(1123.26723);
     結(jié)果:1123

根據(jù)年齡分組計算id的平均值

select age,avg(id) from user group by age;

效果:

效果

查詢每個年齡下的用戶的數(shù)量

select age,count(*) from user group by age;

效果:

效果

查詢每個年齡下 id 最高的用戶

select age,max(id) from user group by age;

二、having篩選

(1).查詢age-id>15的用戶

select name,age-id from user where (age-id)>15;
select name,(age-id) as demo from user where demo>15;        /* 錯誤 */
select name,(age-id) as demo from user where 1 having demo>15;   /* 正確 優(yōu)化 */
注意:博主在使用index作為替代變量時執(zhí)行語句會出錯,可能index為MySQL保留字,望讀者注意

(2).where-having-group綜合練習(xí)題

有如下表及數(shù)據(jù)

name subject score
張三 數(shù)學(xué) 90
張三 語文 50
張三 地理 40
李四 語文 55
張三 數(shù)學(xué) 45
張三 數(shù)學(xué) 30

要求: 查出兩門及兩門以上不及格者的平均成績:

select name,sum(score<60) as gk,avg(score) as pj
     -> from  result group by name
     -> having gk>=2;

三、order by排序

  • 降序: desc
  • 增序: asc [默認(rèn)asc]
  • 多列排序: 逗號隔開,依次添加條件即可
/* 將用戶按照age增序排序 */
select * from user order by age;
/* 將用戶按照age進(jìn)行降序排序 */
select * from user order by age desc;
/* 先按照age進(jìn)行增序排序,再為分組好的age序列根據(jù)id進(jìn)行降序排序;*/
select * from user order by age asc,id desc;

四、limit語法

找出年齡前三名的同學(xué)
select * from user order by age limit 0,3;
0: 偏移量。默認(rèn)是0,可以省略
3: 取值個數(shù)
  • LIMIT可以用來實現(xiàn)分頁功能
  • 但是數(shù)據(jù)太大的時候limit表現(xiàn)的并不是很完美,這里鏈接以下掘金里的一個文章,有興趣的讀者可以去看一下: MySQL之LIMIT性能問題

練習(xí):
利用where,group by,having,order by,limit 其中幾種的組合指令查詢每個age段里id最大的用戶
注意: 如果選擇組合使用這幾種,那么他們的順序必然是固定的,不可顛倒

/* 利用子查詢進(jìn)行查找,具體子查詢詳情在---where型子查詢---中再講 */
select age,id,name from user where id in (select max(id) from user group by age);

五、where型子查詢

查出年齡最大的用戶:

/* 排序法(浪費資源) */
select name,age from user order by age limit 0,1;
/* 下面一條是博主嘗試的一個****錯誤的思路****,無法執(zhí)行 */
select id,name max(age) as max from user where 1 having age=max;
/* 利用子查詢(正確、高效) */
select name,age from user where age=(select max(age) from user);

注意: 子查詢語句只能有一個返回結(jié)果,有多個返回結(jié)果不然會報錯。

六、from型子查詢

理解: select 語句返回的結(jié)果也是一張表,大膽的把select的結(jié)果當(dāng)作另一個select語句所要查詢的表即可

查詢年齡為19中id最大的用戶:

select id,name,age from (select * from user where age=19) as tmp order by id desc limit 0,1;

查詢出編號為19的商品所在的欄目的名稱:
注意: 此表中只包含欄目的編號,并不包含欄目的名稱,欄目的編號與名稱對應(yīng)關(guān)系在另外一張表中.可以用子查詢或下面的連接查詢

/* 子查詢 */
select name from xxx1 where index=(select index from xxx2 where id =19);
xxx1: 欄目的編號與名稱對應(yīng)關(guān)系表
xxx2: 商品表

/* 連接查詢 */
略

七、exists型子查詢

理解: 如果子查詢有結(jié)果,主查詢就繼續(xù)根據(jù)結(jié)果去查詢;如果子查詢沒有結(jié)果,主查詢就不繼續(xù)根據(jù)此結(jié)果查詢

**用exists型子查詢,查出所有里面有商品的欄目

select * from category 
     where exists (select * from goods where goods.cat_id=category.cat_id)
/* c此語句會將category表中的所有 cat_id 與進(jìn)行查詢 */

八、新手1+ N查詢(反例)

$sql = 'select cat_id,shop_price from goods where shop_price>2000';
$rs = mysql_query($sql);

$data = array();
while() {
     $row...
}

$data = array(7條商品);

foreach($data in $goods) {
     $sql = 'select cat_name from category where cat_id = $goods['cat_id']';
}
  • 即: 一條語句--->N條查詢
  • 這種寫法是非常低級的寫法
  • 可以用內(nèi)聯(lián)查詢解決這種問題

九、內(nèi)聯(lián)查詢

語法:

select xxxx from
     -> table1 inner join table2 on table1.xx=table2.xx;

有這樣兩張表:(假如說boy與girl表中hid匹配上的用戶就是搭檔關(guān)系)


boy and girl

要求: 將這兩張表hid相同的人(name)組合起來(輸出所有搭檔組合)

select boy.hid,boy.bname,girl.hid,boy.gname
     -> from
     -> boy inner join girl 
     -> on boy.hid=girl.hid;

輸出結(jié)果:

輸出結(jié)果

十、左連接及右連接查詢

  • 理解:還是上面的例子。輸出所有boy,有搭檔girl匹配顯示上,沒有搭檔就顯示為NULL
  • 左連接即以左邊數(shù)據(jù)為準(zhǔn)查詢右邊數(shù)據(jù),查不到補(bǔ)NULL

(1).左連接:

select boy.hid,boy.bname,girl.hid,boy.gname
     -> from
     -> boy left join girl
     -> on boy.hid=girl.hid;

左連接查詢結(jié)果:

左連接查詢結(jié)果

(2).右連接

select boy.hid,boy.bname,girl.hid,boy.gname
     -> from
     -> boy right join girl
     -> on boy.hid=girl.hid;

右連接查詢結(jié)果:

右連接查詢結(jié)果

(3).練習(xí):查詢所有商品的商品名,欄目名,價格
注: 欄目名在另外一張表中,因此要進(jìn)行連接查詢

select goods_id,cat_name,goods.cat_id,shop_price
     -> from
     -> goods left join category on goods.cat_id=category.cat_id;

(4).練習(xí):查詢所有第四欄目下所有商品的商品名,欄目名,價格

select goods_id,cat_name,goods.cat_id,shop_price
     -> from
     -> goods left join category on goods.cat_id=category.cat_id
     -> where goods.cat_id=4;

(5).一道面試題
有如下兩張表:

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

  • Match的hosteamID與guestTeamID都與Team中的teamID關(guān)聯(lián)
  • 題目: 查出2006-6-1到2006-7-1之間舉行的所有比賽,并且用以下形式列出:
    拜仁 2:0 不來梅 2006-6-21
select mid,t1.tname as hname,mres,t2.tname as gteam,matime
     -> from
     -> m inner join t as t1 on m.hid=t1.tid inner join t as t2 on m.gid=t2.tid
     -> where matime between '2006-06-01' and '2006-07-01';

查詢結(jié)果:

查詢結(jié)果

十一、union查詢

使用場景: 2條語句,各自的where條件非常復(fù)雜,可以簡化成簡單條件,再union

例:找出年齡(age)為18和20的用戶

select name,age from user where age=18
     -> union
     -> select name,age from user where age=20;
  • union語句必須滿足一個條件:各語句取出的列數(shù)相同
  • 列名稱不一定要相等,列名稱會使用第一條sql的列名為準(zhǔn)
  • 注意: 使用union時,完全相等的行將會被合并。
    并且: 合并是比較耗時的操作。使用'union all'避免合并
    union的子句中,不用謝order by。sql語句合并后得到的結(jié)果可以oeder by。

例題:
有如下兩張表,將兩張表中的數(shù)num加起來。

image.png

select id,sum(num)
     -> from
     -> (select * from a
     -> union all
     -> select * from b) as tmp
     -> group by id;

十二、查詢練習(xí)

user表中的數(shù)據(jù)(練習(xí)用):

image.png

1.基礎(chǔ)查詢 where 的練習(xí)

查詢滿足以下條件的商品:

1.1.主鍵為 3 的用戶

select * from user where id=3;

1.2.年齡不是 19 的用戶

1. select name,age from user where age!=19;
2. select name,age from user where age<>19;

1.3.年齡大于19的用戶

select name,age from user where age>19;

1.4.年齡低于或等于19的用戶

select name,age from user where age<=19;

1.5.年齡為19或20的用戶(不許用or)

/*  1. select * from user where age=19 or age=20; */
2. select * from user where age=19 || age=20;
3. select * from user where age in (19,20);

1.6.找出18<=年齡<=19的用戶(不許用and)

/* 1. select name,age from user where age>=18 and age<=19; */
2. select name,age from user where age between 18 and 19;

1.7.找出年齡不是18且不是19的用戶(and或not in分別實現(xiàn))

1. select name,age from user where age!=18 and age!=19;
2. select name,age from user where age not in (18,19);

1.8.找出年齡大于17且小于19,或者年齡大于20小于22的用戶

select name,age from user where (age>17 and age<19) or (age>20 and age<22);

1.9.找出年齡為19歲并且id<2或>4,并且name為'zk'的用戶

select * from user 
     where age=19 and (id<2 or id>4) and name='zk';
/* 括號是必要的,因為不加括號就會使and先執(zhí)行 */

1.10.找出name為'zk'的用戶

(注意:不存在'zk'在這個用戶,但是他有兩個兒子。此處假設(shè)有father這個表項)

select * from user where name in ('zk1','zk2');

1.11.找出name以'w'開頭的用戶

1. select name,age from user where name like 'w%';

/* 匹配以name'w'開頭并且后面有兩個任以字符的用戶 */
2. select name,age from user where name like 'w__';   

1.12.找出年齡在18到20之間,并且id>3,name以'z'開頭的用戶

1. select name,age from user where age>18 and age<20 and id>3 and name like 'z%';
2. select name,age from user where age between 18 and 20 and id>3 and name like 'z%';

2.一道面試題

有如下表(girl)和數(shù)組
把num處于[20,29]之間的數(shù)值改為20
把num處于[30,39]之間的數(shù)值改為30,

num
3
12
15
25
23
29
34
37
32
update girl set num=floor(num/10)*10 where num between 20,30;

3.練習(xí)題

把user表中用戶名為'慕容xxxx'的用戶,改為'諸葛xxxx'
提示: 大膽的把列看成變量,參與運算,甚至調(diào)用函數(shù)來處理。
substring(), concat()

update user set name=concat('諸葛',substring(name,3)) where name like '慕容____';

友情鏈接:

MySQL基礎(chǔ)教程全網(wǎng)最全1(基本指令操作)
MySQL基礎(chǔ)教程3-DDL(創(chuàng)建表)
MySQL基礎(chǔ)教程4-細(xì)節(jié)知識點

文集推薦:

Java基礎(chǔ)方法集1
Python基礎(chǔ)知識完整版
Spring Boot學(xué)習(xí)筆記
Linux指令進(jìn)階
Java高并發(fā)編程
SpringMVC基礎(chǔ)知識進(jìn)階
Mysql基礎(chǔ)知識完整版
健康管理系統(tǒng)學(xué)習(xí)花絮(學(xué)習(xí)記錄)
Node.js基礎(chǔ)知識(隨手筆記)
MongoDB基礎(chǔ)知識
Dubbo學(xué)習(xí)筆記
Vue學(xué)習(xí)筆記(隨手筆記)

聲明:發(fā)表此文是出于傳遞更多信息之目的。若有來源標(biāo)注錯誤或侵犯了您的合法權(quán)益,請作者持權(quán)屬證明與本我們(QQ:981086665;郵箱:981086665@qq.com)聯(lián)系聯(lián)系,我們將及時更正、刪除,謝謝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容