Python 高級 15(2) 數據表操作

2.5 數據表查詢操作

學習目標

能夠熟練對數據表進行各種查詢操作

--------------------------------------------------------------------------------

2.5.1 數據查詢操作介紹

在數據庫操作中,使用頻率最多的是查詢操作。

查詢數據時,根據不同的需求,條件對數據庫中的數據進行查詢 ,并返回結果。

2.5.2 準備工作,導入數據庫

在查詢之前,首先要有數據表和相應的數據。

在 輔助資料中 有 school.sql 文件,通過導入該文件來快速準備數據。

? 導入之前需要先創建一個數據庫

? 使用新創建的數據庫

? 使用 source 文件地址 導入數據

? ? ? 注意,導入數據庫時的文件地址盡量使用絕對路徑,或者把文件放在家目錄下

2.5.3 單表查詢數據

查詢數據庫使用 select 命令。 這個命令相對比較復雜。可變化樣式較多,這里分功能依次講解。

1.數據表單表查詢數據總結:

select 字段名[,(字段名…)] from 表名;

? <1>查詢數據表中所有數據

? ? ? 語法:select * from 表名

? ? ? select * from t_student;

? <2>查詢指定字段的顯示

? ? ? 語法:select 字段1,字段2,... from 表名

? ? ? select c_id,c_name,c_address from t_student;

? <3>as 別名

? ? ? 在查詢時,默認結果顯示的字段和表中字段名相同,可以通過別名來修改顯示的樣

? ? ? 給字段起別名

? ? ? ? ? ■? 語法:select 字段1 as 別名,字段2 別名,... from 表名

? ? ? ? ? ■ select c_id as 學號 ,c_name as 姓名 ,c_address 地址 from t_student;

? ? ? 給數據表起別名

? ? ? ? ? ■ 語法:select 字段1,字段2 別名,... from 表名 as 別名

? ? ? 注意:

? ? ? ? ? ■ 在給字段或表起別名時,可以使用 as ,也可以直接在字段后跟別名,省略 as 。

? ? ? ? ? ■ 如果起了別名,原名將不起作用!后面的語句中只能使用別名

? <4>消除重復數據distinct

? ? ? 在查詢數據時,查詢結果可能會有很多重復的數據,如果不想重復,可以使用 distinct 來實現去重。

? ? ? 語法:select distinct 字段名 from 表名

? ? ? 語法:select distinct 字段名1 字段名2 from 表名

? ? ? select distinct c_address from t_student;

? ? ? 注意:

? ? ? ? ? ■ 可以指定多個字段名

? ? ? ? ? ■ distinct 在去重時,會比較所有的指定字段,只有完全相同時才認為是重復的。

? <5>帶條件查詢where

? ? ? where 子句 查詢數據時,需要根據不同的需求設置條件。 通過 where 子句來設置查詢條件

? ? ? 語法:select 字段名…? form? 表名 where? 條件;

? ? ? select * from t_student where c_gender='男';

? ? ? 注意:

? ? ? ? ? ■ where 條件可以使用運算符操作。

? 1>比較運算符

? ? ? 等于: =

? ? ? 大于: >

? ? ? 大于等于: >=

? ? ? 小于: <

? ? ? 小于等于: <=

? ? ? 不等于: != 或 <>

? ? ? ? ? ■ select * from t_student where c_age < 20;

? ? ? 注意sql中只有一個等號,沒有==這種形式

? 2>邏輯運算符

? ? ? and

? ? ? or

? ? ? not

? ? ? ? ? ■ select * from t_student where c_age < 20 and c_gender = '女';

? <6>模糊查詢like

? ? ? like(這是一個操作符)

? ? ? % 表示任意多個任意字符

? ? ? _ 表示一個任意字符

? ? ? ? ? ■ select * from t_student where c_name like '孫';

? ? ? ? ? ■ select * from t_student where c_name like '孫%';

? ? ? ? ? ■ select * from t_student where c_name like '孫_';

? <7>范圍查詢,非連續范圍in,連續范圍between ... and ...

? ? ? in 表示在一個非連續的范圍內 , 可以使用 or 實現

? ? ? ? ? ■ select * from t_students where id in(1,3,8);

? ? ? between ... and ... 表示在一個連續的范圍內,可以使用 and 實現 ```

? ? ? ? ? ■ select * from t_students where c_id between 2 and 5;

? ? ? ? ? ■ 相當于select * from t_students where c_id >=2 and c_id <= 5;

? <8>空判斷is null、is not null

? ? ? 在數據庫中,允許在數據添加是沒有數據,使用空值來表示。 空值不等于0,也不等于'',需要使用特殊的判斷方式

? ? ? 判斷空值

? ? ? ? ? ■ 語法:is null

? ? ? ? ? ? ? select * from t_student where c_age is null;

? ? ? 判斷非空值

? ? ? ? ? ■ 語法:is not null

? ? ? ? ? ? ? select * from t_student where c_age is not null;

? <9>查詢結果排序order by

? ? ? 排序order by(子句)是一個在查詢數據時非常重要的操作。比如買東西時,想按一定的條件進行有序顯示。就需要使用排序

? ? ? 排序使用 order by 子段名 asc(默認) 升序 / desc 降序

? ? ? 語法:select * from 表名 order by 列1 asc/desc [,列2 asc/desc,...]

? ? ? 單字段排序

? select * from t_student order by c_age;

? select * from t_student order by c_age asc;

? 默認使用就是升序排序,可以不指定 asc ,效果相同。

? ? ? 多字段排序

? ? ? ? ? ■ 可以對多個字段進行排序,只需將字段的排序方式依次寫在 order by 后面即可,字段間使用逗號分隔

? ? ? ? ? ■ select * from t_student order by c_age desc,c_id asc;

? <10>分頁查詢limit

? ? ? 查詢數據庫時,由于數據較多,在顯示過程中不可能將數據全部顯示。 可以使用分頁查詢,只顯示指定的一部分數據

? ? ? 語法:select 字段名 from 表名 limit start=0(開始索引默認為0),count(記錄條數)

? ? ? ? ? ■ 從start開始,獲取count條數據,start默認值為0

? ? ? ? ? ■ 需要獲取數據的前n條的時候可以直接寫 limit n

? ? ? ? ? ■ select * from t_student limit 3;

? ? ? ? ? ■ select * from t_student limit 2,3;

? ? ? ? ? ■ 注意:查詢第 N 頁 M 條數據,可以通過公式算出:(N - 1) * M

? <11>聚合函數

? ? ? 在 MySQL 中提供了一些定義好的函數,利用這些函數提供對數據的統計功能,聚合函數一般配合分組功能一起使用。

? ? ? 1>sum 求和函數 對指定的字段求和

? ? ? ? ? ■ select sum(c_age) from t_student;

? ? ? 2>avg 求平均值函數 對指定字段求平均值

? ? ? ? ? ■ select avg(c_age) from t_student;

? ? ? 3>max 求最大值函數

? ? ? ? ? ■ select max(c_age) from t_student where c_gender = '男';

? ? ? 4>min 求最小值函數

? ? ? ? ? ■ select min(c_age) from t_student where c_gender = '女';

? ? ? 5>count 統計記錄總數

? ? ? ? ? ■ select count(*) from t_student;

? ? ? ? ? ■ select count(*) from t_student where c_gender = '女';

? ? ? 6>group_concat() 拼接分組中的數據

? <12>分組group by

? ? ? 分組就是將相同數據放到一起進行處理。 單純的分組是沒有意義的,需要配合聚合函數一起使用。

? ? ? group by的含義:將查詢結果按照1個或多個字段進行分組,字段值相同的為一組

? ? ? group by可用于單個字段分組,也可用于多個字段分組

? ? ? 語法: select 分組的字段名,聚合函數... from 表名 group by 分組字段名 having 分組后的條件

? ? ? 注意:

? ? ? ? ? ■ 在執行 group by 分組時,select 后只能有被分組的字段,不允許有其它字段,除非這些字段在聚合函數中

? ? ? ? ? ? ? 查詢顯示的字段必須和分組的字段相同

? ? ? ? ? ■ 分組一般配合聚合函數使用,做數據統計功能

? ? ? ? ? ■ 分組后如果需要設置條件要使用 having 指定

? ? ? 1>單字段分組

? ? ? ? ? ■ select c_gender from t_student group by c_gender;

? ? ? 2>多字段分組(了解)

? ? ? ? ? ■ 可以對多個字段進行分組,作用同上,需要注意的是多字段時,只有對應字段完全相同,才能分為同一組

? ? ? ? ? ■? select c_gender,c_address from t_student group by c_gender,c_address;

? ? ? 3>group by + group_concat()

? ? ? ? ? ■ group_concat(字段名)可以作為一個輸出字段來使用,表示分組之后,根據分組結果,使用group_concat()來放置每一組的某字段的值的sel集合

? ? ? ? ? ■ 作用:根據分組結果,使用group_concat()來獲取分組中指定字段的集合

? ? ? ? ? ■ 語法:group_concat(字段名)

? ? ? ? ? ? ? select c_gender,group_concat(c_name) from t_student group by c_gender;

? ? ? 4>分組和聚和函數使用

? ? ? ? ? ■ 單純的使用分組并沒有實際意義,需要使用聚合函數對數據進行處理。

? ? ? ? ? ? ? select c_gender,max(c_age),min(c_age),sum(c_age),avg(c_age),count(*) from t_student group by c_gender;

? ? ? ? ? ? ? select c_gender,max(c_age),min(c_age),sum(c_age),avg(c_age),count(c_age) from t_student group by c_gender;

? ? ? 5>having 作用和 where 類似,用來對分組數據進行篩選

? ? ? ? ? ■ 注意having只能配合分組使用

? ? ? ? ? ■ where 是對 form 表 中取數據時進行篩選

? ? ? ? ? ■ having 是對 group by 分組后的數據進行篩選

? ? ? ? ? ■ 因為在執行順序上,在執行 where 時,分組還沒有執行,得先根據 where 的條件取出數據,才能去取出的數據進行分組。

? ? ? ? ? ? ? select c_gender,group_concat(c_name) from t_student group by c_gender having c_gender = '女';

? ? ? ? ? ? ? select c_gender,group_concat(c_name) from t_student where c_age > 50 group by c_gender having c_gender = '女';

? ? ? 6>分組匯總(無大用,了解即可)

? ? ? ? ? ■ 作用:會在分組下方,加一行,顯示匯總

? ? ? ? ? ■ 語法:with rollup

? ? ? ? ? ? ? select c_gender from t_student group by c_gender with rollup;

? ? ? ? ? ? ? select c_gender,count(*) from t_student group by c_gender with rollup;

2.5.4 多表查詢數據

在數據庫操作中,數據往往不是存在一張表中的,同一個項目中,根據設計范式,數據可能分散在不同的多張表中,這時查詢數據時,就需要多表查詢。

? <1>普通多表查詢(無意義)

? ? ? 作用:直接將表放在from后面,進行讀取。

? ? ? 語法:select 表名.字段 ... from 表名1,表名2...

? ? ? ? ? ■? select * from t_student,t_class;

? ? ? 這種查詢方式沒有任何意義。 在查詢時,數據庫會將表1中的數據逐條和表2中的所有數據連接,組成一條新記錄。 查詢的結果為 M * N 條,實際就是笛卡爾積結果。

? <2>多表查詢連接條件

? ? ? 在多表個表進行查詢時,表與表之間應該是有有關系的,一般會以外鍵的形式來建立表間的關系。 查詢時按照條件建立記錄的匹配規則。 比如學生表中保存了學生的信息和所在班級的ID,班級表中保存了班級的信息。 在查詢學生的班級信息時,可以通過學生表中的班級ID和班級表中的ID匹配進行查詢

? ? ? select t_student.c_name,t_class.c_name? from t_student,t_class where t_student.c_class_id = t_class.c_id;

? <3>內連接查詢(交集)

? ? ? 作用:查詢的結果為兩個表匹配到的數據,內連接指定連接條件取兩表的交集

? ? ? 語法:select * from 表1 inner join 表2 on 表1.列 運算符 表2.列

? ? ? 數據庫默認的連接方式就是內連接查詢,inner join 可以不顯示的寫出來。 不指定連接條件時,實際就是普通多表連接,會以笛卡爾積的形式進行連接。 所以在連接時,必須要給定連接條件。 連接條件使用 on 進行指定。盡量不要使用 where,where在其它連接方式時,指定的連接條件無效。

? ? ? ? ? ■ select ts.c_name, tc.c_name from t_student as ts inner join t_class tc on ts.c_class_id = tc.c_id;

? <4>左連接查詢

? ? ? 作用:查詢的結果為根據左表中的數據進行連接,如果右表中沒有滿足條件的記錄,則連接空值。

? ? ? 注意:連接條件只能使用 on 指定

? ? ? 語法: select * from 表1 left join 表2 on 表1.列 運算符 表2.列

? ? ? ? ? ■ select ts.c_name, tc.c_name from t_student as ts left join t_class tc on ts.c_class_id = tc.c_id;

? <5>右連接查詢

? ? ? 作用:查詢的結果為根據右表中的數據進行連接,如果左表中沒有滿足條件的記錄,則連接空值。

? ? ? 注意:連接條件只能使用 on 指定

? ? ? 語法: select * from 表1 right join 表2 on 表1.列 運算符 表2.列

? ? ? ? ? ■ select ts.c_name, tc.c_name from t_student as ts right join t_class tc on ts.c_class_id = tc.c_id;

? ? ? 在實際工作中,右連接使用的非常少,因為左連接完全可以替代右連接,在連接過程中,只需要調整表的順序即可。

? <6>子查詢

? ? ? 作用:在一個 select 語句中,嵌入了另外一個 select 語句, 那么被嵌入的 select 語句稱之為子查詢語句,子查詢語句是一個可以獨立執行的查詢語句

? ? ? 語法: select * from 表1 where 條件 運算符 (select 查詢)

? 外部那個select語句則稱為主查詢

? 主查詢和子查詢的關系

? ? ? ? ? ■ 子查詢是嵌入到主查詢中

? ? ? ? ? ■ 子查詢是輔助主查詢的,要么充當條件,要么充當數據源

? ? ? ? ? ■ 子查詢是可以獨立存在的語句,是一條完整的 select 語句

? 1>標量子查詢

? ? ? 作用:子查詢返回的結果是一個數據(一行一列)

? ? ? 語法:主查詢 where 條件 比較運算符 (列子查詢)

? ? ? ? ? ? ? 查詢班級中年齡大于平均年齡的學生信息

? ? ? ? ? ? ? 查詢班級學生平均年齡

? ? ? ? ? ? ? 查詢大于平均年齡的學生

? ? ? ? ? ? ? select * from t_student where c_age > (select avg(c_age) from t_student);

? 2>列級子查詢

? ? ? 作用:子查詢返回的結果是一列(一列多行)

? ? ? 語法:主查詢 where 條件 in (列子查詢)

? ? ? ? ? ? ? 查詢所有學生所在班級的班級名稱

? ? ? ? ? ? ? 找出學生表中所有的班級 id

? ? ? ? ? ? ? 找出班級表中對應的名字

? ? ? ? ? ? ? select * from t_class where c_id in (select c_class_id from t_student);

? 3>行級子查詢

? ? ? 作用:子查詢返回的結果是一行(一行多列)

? ? ? 語法:主查詢 where (字段1,2,...) = (行子查詢)

? ? ? ? ? ? ? 查找班級年齡最大,所在班號最小的的學生

? ? ? ? ? ? ? 找出最大年齡和最小班號

? ? ? ? ? ? ? 找出年齡和班號滿足條件的學生

? ? ? ? ? ? ? select * from t_student where(c_age,c_class_id) = (select max(c_age),min(c_class_id) from t_student);

? <7>自連接查詢

? ? ? 作用:在查詢數據時,只有一張表,查詢時使用自己連接自己。

? ? ? 語法: select * from 表1 inner join 表2 on 表1.列 運算符 表2.列 where 條件

? 為什么需要自連接

? ? ? 設計表結構來存儲 全國 所有的省份和 全國所有的市

? ? ? 設計省信息的表結構provinces

? ? ? id 省的編號

? ? ? ptitle 省名稱

? ? ? 設計市信息的表結構citys

? ? ? id 市編號

? ? ? ctitle 市名稱

? ? ? proid 市所屬的省的編號

? citys表的proid表示城市所屬的省,對應著provinces表的id值

? 將兩個表合為一個

? 定義表areas,結構如下

? ? ? ? ? ■ id

? ? ? ? ? ■ atitle

? ? ? ? ? ■ pid

? ? ? 關于這個表的說明:

? ? ? ? ? ■ 因為省沒有所屬的省份,所以可以填寫為null

? ? ? ? ? ■ 城市所屬的省份pid,填寫省所對應的編號id

? ? ? ? ? ■ 這就是自關聯,表中的某一列,關聯了這個表中的另外一列,但是它們的業務邏輯含義是不一樣的,城市信息的pid引用的是省信息的id

? ? ? ? ? ■ 在這個表中,結構不變,可以添加區縣、鄉鎮街道、村社區等信息

? areas表和自身進行連接這種形式的連接 就成為自連接。

? 創建areas表的語句如下:

? ? ? 注意,表所在的數據庫字符集必須是utf8的,如果不是會導入數據出錯

? ? ? ? ? ■ create table areas(aid int primary key,atitle varchar(20),pid int);

? 從sql文件中導入數據

? ? ? source areas.sql;

? 查詢一共有多少個省

? ? ? select count(*) from areas where pid is null;

? 例1:查詢省的名稱為“山西省”的所有城市

? ? ? select city.* from areas as city inner join areas as province on city.pid=province.aid where province.atitle='山西省';

? 例2:查詢市的名稱為“廣州市”的所有區縣

? ? ? select dis.* from areas as dis inner join areas as city on city.aid=dis.pid where city.atitle='廣州市';

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,208評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,746評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,666評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,477評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,960評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,200評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,726評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,617評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,807評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,049評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,425評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,674評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,432評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,769評論 2 372