數據查詢操作介紹
在數據庫操作中,使用頻率最多的是查詢操作。
查詢數據時,根據不同的需求,條件對數據庫中的數據進行查詢 ,並返回結果

單表查詢數據
查詢數據庫使用 select 命令。 這個命令相對比較復雜。可變化樣式較多,這里分功能依次講解。
-
查詢數據表中所有數據 語法:select * from 表名
select * from t_student;
-
查詢指定字段的顯示 語法:select 字段1,字段2,... from 表名
select c_id,c_name,c_address from t_student;
-
as 別名 在查詢時,默認結果顯示的字段和表中字段名相同,可以通過別名來修改顯示的樣式 語法:select 字段1 as 別名,字段2 別名,... from 表名
select c_id as 學號 ,c_name as 姓名 ,c_address 地址 from t_student;
在給字段起別名時,可以使用 as ,也可以直接在字段后跟別名,省略 as 。
-
消除重復數據 在查詢數據時,查詢結果可能會有很多重復的數據,如果不想重復,可以使用 distinct 來實現去重。 語法:select distinct 字段名 from 表名
select distinct c_address from t_student;
注意:distinct 在去重時,會比較所有的指定字段,只有完全相同時才認為是重復的。 -
帶條件查詢 where 子句 查詢數據時,需要根據不同的需求設置條件。 通過 where 子句來設置查詢條件
select * from t_student where c_gender='男';
-
比較運算符
- 等於: =
- 大於: >
- 大於等於: >=
- 小於: <
- 小於等於: <=
-
不等於: != 或 <>
select * from t_student where c_age < 20;
-
邏輯運算符
- and
- or
- not
select * from t_student where c_age < 20 and c_gender = '女';
-
模糊查詢
- 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 '孫_';
-
范圍查詢
- in 表示在一個非連續的范圍內 , 可以使用 or 實現
select * from t_students where id in(1,3,8);
select * from t_students where id =1 or id =3 or id =8);
- between ... and ... 表示在一個連續的范圍內,可以使用 and 實現 ```

- in 表示在一個非連續的范圍內 , 可以使用 or 實現
-
空判斷 在數據庫中,允許在d數據添加是沒有數據,使用空值來表示。 空值不等於0,也不等於‘’,需要使用特殊的判斷方式
-
判斷空值
語法:is nullselect * from t_student where c_age is null;
-
判斷非空值 語法:is not null
select * from t_student where c_age is not null;
-
-
查詢結果排序 排序是一個在查詢數據時非常重要的操作。比如買東西時,想按一定的條件進行有序顯示。就需要使用排序
排序使用 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;
-
-
分頁查詢查詢數據庫時,由於數據較多,在顯示過程中不可能將數據全部顯示。 可以使用分頁查詢,只顯示指定的一部分數據 語法:select from 表名 limit start=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
-
聚合函數在MySQL中提供了一些定義好的函數,利用這些函數提供對數據的統計功能。 常用的聚合函數如圖:

-
sum 求和函數 對指定的字段求和
select sum(c_age) from t_student;
-
avg 求平均值函數 對指定字段求平均值
select avg(c_age) from t_student;
-
max 求最大值函數
select max(c_age) from t_student where c_gender = '男';
-
min 求最小值函數
select min(c_age) from t_student where c_gender = '女';
-
count 統計記錄總數
select count(*) from t_student; select count(*) from t_student where c_gender = '女';
-
-
分組 分組就是將相同數據放到一起進行處理。 單純的分組是沒有意義的,需要配合聚合函數一起使用。 語法: select 分組的字段名,聚合函數... from 表名 group by 分組字段名 having 分組后的條件
注意:在執行 group by 分組時,select 后只能有被分組的字段,不允許有其它字段,除非這些字段在聚合函數中
- 單字段分組 ```sql select c_gender from t_student group by c_gender; ``` <img src='images/88.png'> - 多字段分組(了解) 可以對多個字段進行分組,作用同上,需要注意的是多字段時,只有對應字段完全相同,才能分為同一組 ```sql select c_gender,c_address from t_student group by c_gender,c_address; ``` <img src='images/89.png'> - group_concat() 作用:根據分組結果,使用group_concat()來獲取分組中指定字段的集合 語法:group_concat(字段名) ```sql select c_gender,group_concat(c_name) from t_student group by c_gender;s ``` <img src='images/90.png'> - 分組和聚和函數使用 單純的使用分組並沒有實際意義,需要使用聚合函數對數據進行處理。 ```sql 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; ``` <img src='images/91.png'> - having條件子句 having 作用和 where 類似,用來去分組數據進行篩選 where 是對 form 表 中取數據時進行篩選 having 是對 group by 分組后的數據進行篩選 因為在執行順序上,在執行 where 時,分組還沒有執行 得先根據 where 的條件取出數據,才能去取出的數據進行分組。 ```sql 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 = '女'; ``` <img src='images/92.png'> - 分組匯總(無大用,了解即可) 作用:會在分組下方,加一行,顯示匯總 語法:with rollup ```sql 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; ``` <img src='images/93.png'>
多表查詢數據
在數據庫操作中,數據往往不是存在一張表中的,同一個項目中,根據設計范式,數據可能分散在不同的多張表中,這時查詢數據時,就需要多表查詢。
-
普通多表查詢(無意義) 作用:直接將表放在from后面,進行讀取。 語法:select 表名.字段 ... from 表名1,表名2...
select * from t_student,t_class;
這種查詢方式沒有任何意義。 在查詢時,數據庫會將表1中的數據逐條和表2中的所有數據連接,組成一條新記錄。 查詢的結果為 M * N 條,實際就是笛卡爾積結果。
-
多表查詢連接條件 在多表個表進行查詢時,表與表之間應該是有有關系的,一般會以外鍵的形式來建立表間的關系。 查詢時按照條件建立記錄的匹配規則。 比如學生表中保存了學生的信息和所在班級的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;
-
表別名 在多表操作時,由於表的名字比較長,在寫SQL語句時非常不方便。可以在查詢 時,給表起個別名,代替表名來操作 語法: select 別名.字段名... from 表1 as 表1別名,表2 表2別名... [條件]
select ts.c_name as '姓名' , tc.c_name '班級名' from t_student as ts,t_class tc where ts.c_class_id = tc.c_id;
-
內連接查詢 作用:查詢的結果為兩個表匹配到的數據 語法: 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;
-
左連接查詢 作用:查詢的結果為根據左表中的數據進行連接,如果右表中沒有滿足條件的記錄,則連接空值。 語法: 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;
-
右連接查詢 作用:查詢的結果為根據右表中的數據進行連接,如果左表中沒有滿足條件的記錄,則連接空值。 語法: 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;
在實際工作中,右連接使用的非常少,因為左連接完全可以替代右連接,在連接過程中,只需要調整表的順序即可。
-
子查詢 作用:作用:在一個 select 語句中,嵌入了另外一個 select 語句, 那么被嵌入的 select 語句稱之為子查詢語句 語法: select * from 表1 where 條件 運算符 (select 查詢)
- 外部那個select語句則稱為主查詢
-
主查詢和子查詢的關系
- 子查詢是嵌入到主查詢中
- 子查詢是輔助主查詢的,要么充當條件,要么充當數據源
- 子查詢是可以獨立存在的語句,是一條完整的 select 語句
-
標量子查詢 作用:子查詢返回的結果是一個數據(一行一列) 語法:主查詢 where 條件 比較運算符 (列子查詢)
-
查詢班級中年齡大於平均年齡的學生信息
- 查詢班級學生平均年齡
- 查詢大於平均年齡的學生
select * from t_student where c_age > (select avg(c_age) from t_student);
-
-
列級子查詢 作用:子查詢返回的結果是一列(一列多行) 語法:主查詢 where 條件 in (列子查詢)
-
查詢所有學生所在班級的班級名稱
- 找出學生表中所有的班級 id
- 找出班級表中對應的名字
select * from t_class where c_id in (select c_class_id from t_student);
-
-
行級子查詢 作用:子查詢返回的結果是一行(一行多列) 語法:主查詢 where (字段1,2,...) = (行子查詢)
-
查找班級年齡最大,所在班號最小的的學生
- 找出最大年齡和最小班號
- 找出年齡和班號滿足條件的學生
select * from t_student where(c_age,c_class_id) = (select max(c_age),min(c_class_id) from t_student);
-
-
自連接查詢 作用:在查詢數據時,只有一張表,查詢時使用自己連接自己。 語法: select * from 表1 inner join 表2 on 表1.列 運算符 表2.列 where 條件
-
為什么需要自連接
以要設計表結構來存儲 全國 所有的省份和 全國所有的市
- 設計省信息的表結構provinces
- id 省的編號
-
ptitle 省名稱
-
設計市信息的表結構citys
- id 市編號
- ctitle 市名稱
- proid 市所屬的省的編號
citys表的proid表示城市所屬的省,對應着provinces表的id值
如果需要查詢一個省 比如廣東省對應的所有的時的信息 ,我們可以使用兩個表連接查詢。
-
> 問題: 能不能將兩個表合成一張表呢?
-
-
觀察兩張表發現,citys表比provinces表多一個列proid,其它列的類型都是一樣的。
-
這樣做的 **好處**在於: 存儲的都是地區信息,而且每種信息的數據量有限,沒必要增加一個新表,或者將來還要存儲區、鄉鎮信息,都增加新表的開銷太大。
-
定義表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 /home/python/Desktop/areas.sql;
- 創建areas表的語句如下: 注意,表所在的數據庫字符集必須是utf8的,如果不是會導入數據出錯
-
自查詢
-
查詢一共有多少個省
select count(*) from areas where pid is null;
-
查詢省的名稱為“山西省”的所有城市
select city.* from areas as city inner join areas as province on city.pid=province.aid where province.atitle='山西省';
-
查詢市的名稱為“廣州市”的所有區縣
select dis.* from areas as dis inner join areas as city on city.aid=dis.pid where city.ati
轉載:https://blog.csdn.net/weixin_43115821/article/details/82845101
-
