1. 程式人生 > 其它 >03 MySQL查詢操作

03 MySQL查詢操作

技術標籤:MySQLmysql資料庫python

03 MySQL查詢操作

1.建立資料庫

create database python_test charset=utf8
# 提示:在MySQL 語句中,用的是utf8不是utf-8

檢視資料庫

show databases;

使用資料庫

use python_test;

顯示當前使用那個資料庫

select database();

建立一個數據表 存0 1時使用bit 就行 bit(2)可以存4種 tinyint = bit(8) 2^8 = 256

create table studuent(
    id int unsigned primary key auto_increment not null,
    name varchar(20) default '',
    age tinyint unsigned default 0,
    height decimal (5,2),
    gender enum('男', '女', '中性', '保密') default '保密',
    cls_id int unsigned default 0,
    is_delete bit default 0
);

create table classes(
    id int unsigned auto_increment primary key not null,
    name varchar(30) not null
);

向表中插入資料

insert into studuent values
    (0,'小明',18,168.00,2,1,0),
    (0,'小黃',17,175.00,1,2,0),
    (0,'小紅',14,177.00,2,3,0),
    (0,'小漢',11,180.00,3,4,0),
    (0,'小八',12,187.00,3,5,0),
    (0,'小九',13,182.00,4,6,0),
    (0,'小十',18,188.00,3,7,0),
    (0,'小之',17,186.00,2,8,0),
    (0,'小一',10,188.00,2,9,0),
    (0,'小二',15,182.00,3,9,0),
    (0,'小三',18,184.00,2,6,0),
    (0,'小四',19,185.00,4,4,0),
    (0,'小五',13,190.00,2,3,0),
    (0,'小六',14,189.00,2,4,0),
    (0,'小七',15,178.00,2,5,0),
    (0,'十一',15,167.00,1,7,0),
    (0,'十二',18,176.00,1,2,0);

insert into classes values
    (0, "python01期"),
    (0, "python02期"),
    (0, "python04期");
show tables ; #展示表

desc classes;# 建立表詳情

select * from studuent; # 檢視student表中所有資訊

2.查詢

 	select * from studuent;

    # 查詢指定欄位
    select id, name from studuent;

    # 使用as給欄位起別名
    select name as 姓名, age as 年齡 from studuent;

    # select 表明.欄位 ..... from 表名;
    select studuent.name, studuent.age from studuent;

    # 可以通過as給表其別名
    # select 別名.欄位 .... from 表名 as 別名;
    select studuent.name, studuent.age from studuent;
    select s.name, s.age from studuent as s;

    # 消除重複行
    # distinct 欄位
    select distinct gender from studuent;

3.條件查詢

# 條件查詢
# 1. 比較運算子 > < >= <= !=
#--select ... from 表名 where ...;
select * from studuent where age > 18;  # 顯示所有欄位select name, gender, id from studuent where age > 18; # 顯示選中的欄位資訊
#2. 邏輯運算子
# and
# 18到28歲之間的學生資訊
select * from studuent where age > 18 and age < 28;

slect * from studuent where age > 18 and gender = "女";
select * from studuent where age > 18 and gender = 2;

# or
select * from studuent where age > 18 or gender = 2;

# not
# 不在 18歲以上 並且是女性這個範圍內的資訊
select * from studuent where not age > 18 or gender = 2;  # 僅僅對前一個條件起作用

# 不在18歲以上的女性的這個範圍內的資訊
slect * from studuent where not (age > 18 or gender = 2); # not對後面和括號內的都起作用

# 年齡不是小於或者等於18 並且是女性
select * from studuent where not ( age < 18 or age = 18) and gender = 2;
select * from studuent where not age <=18 and gender = 2;

#3. 模糊查詢(進行匹配 所以效率低)
# like
 -- % 替換零個或者多個
 -- _ 替換一個

# eg:查詢姓名以小開頭的資訊
select * from studuent where name like "小%";
# 查詢姓名當中有小的名字
select * from studuent where name like "%小%";
# eg:查詢有兩個字的名字
select * from studuent where name like "小_";
# eg:查詢兩個字以上的名字資料資訊
slect * from studuent where name like "__%";

# rlike (正則表示式)
# 查詢以小開始的資訊
select * from studuent where name rlike "^小.*";

# 查詢已小開始 九結束的資訊
select * from studuent where name rlike "^小*九$"
select * from studuent where name regexp "^小*九$"

select * from studuent where name regexp "一"

4.範圍查詢

# in (1,3,8)表示在一個非連續的範圍內
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
    # 查詢年齡為18,34的人資訊
    select name from studuent where age = 18 or age = 34;
    select name from studuent where age = 18 or age = 34 or age = 12;
    select name, age  from studuent where age in (12, 18, 34);

# not in不非連續的範圍內
    # 不是年齡為18, 34的人資訊
    select name, age from studuent where age not in (12, 18, 34);


# between ... and ...表示在什麼範圍之內  屬於連續問題查詢
    # 在什麼範圍
    select name, age from studuent where age between 12 and 34;

    # 不再範圍
    select name, age from studuent where age not between 12 and 34;
    select name, age from studuent where not age between 12 and 34;       # not ... between ... and 是一種語法

    select name, age from studuent where age not (between 12 and 34);       # 語法錯誤


# 判斷空 is null
    # 判斷身高為空
    select name from studuent where age is null;

# 判斷非空 is not null
    select name from studuent where age is not null;

5.排序

# 排序
    # order by 欄位
    # asc 從小到達排序 即升序
    # desc 從大到小排序 即將序
    # 在排序過程中遇到相同值時會按照主鍵進行排序

    # 查詢年齡到18~34之間的男性,按照年齡從小到達排序
    select * from studuent where (age between 12 and 23) and gender = 1 order by age desc;


    # order by 多個欄位
    select * from studuent where (age between 12 and 23) and gender = 1 order by age desc, gender desc, height desc; # 在年齡相同的情況下按照性別按照升序的方式排序,如果前面排序欄位都不相同則後面的欄位不執行
     

6. 聚合函式

聚合函式:一些普通的函式得出的一些結論,不允許與其他欄位混合使用, 想要用就要使用分組, 分組和聚合函式一起使用

# 求總數
# count
# 查詢男性有多少人
select count(name), avg(height) from studuent;
select * from studuent where gender = 1;
select count(*) from studuent where gender = 1;
select count(*) as 男性人數 from studuent where gender = 1;

# 求最大值
# max
# 查詢最大年齡
select * from studuent;
select max(age) as 最大值 from studuent;

# 最小值
# min 秋女性年齡最小值
select min(age) as 最小值 from studuent where gender = 2;

# 求和
# sum
# 求所有年齡總和
select sum(age) as 和 from studuent;

# 求平均值
# avg
select sum(age)/count(*) as 均值 from studuent;
select avg(age) as 最大值 from studuent;

# 四捨五入
# round(123.232221133, 4)
select round(avg(age), 2) as 四捨五入 from studuent;

# 經驗:語言裡面小數是由誤差的,例如銀行當中,但是整數沒有
# 舉例:3.14 我們乘以100變成整數。

6.1 分組

分組和聚合函式一起使用,否則分組就沒啥意義
GROUP BY關鍵字通常和集合函式一起使用,比如MAX()、MIN()、COUNT()、SUM()、AVG()。
例如,要返回每個水果供應商提供的水果種類,這時就要在分組過程中用到COUNT()函式,把資料分為多個邏輯組,並對每個組進行集合計算。

# 按照性別分組,查詢所有的性別
select gender, count(gender) from studuent group by gender;   # 先分組,再從組內取資料

# 計算每種性別的人數
select gender, count(*) from studuent group by gender;  # count(*)表示對分組的計算個數  count(*)指從分組內計算個數

desc studuent;
# 按照性別分組
select gender, count(gender), group_concat(name, ' ', id, ' ', height, ' ', cls_id) from studuent group by gender;

# 計算男性的人數
select gender, count(*) from studuent where gender = 1;
select gender, count(*) from studuent where gender = 1 group by gender;
+--------+----------+
| gender | count(*) |
+--------+----------+
| 男     |        3 |
+--------+----------+
1 row in set (0.00 sec)

# group_concat(...) 顯示的內容
#在MySQL中,可以在GROUP BY子句中使用GROUP_CONCAT()函式,將每個分組中各個欄位的值顯示出來。
select gender, group_concat(name, age, id), count(*) from studuent where gender = 1 group by gender;
+--------+---------------------------------+----------+
| gender | group_concat(name, age, id)     | count(*) |
+--------+---------------------------------+----------+
| 男     | 小黃172,十一1516,十二1817       |        3 |
+--------+---------------------------------+----------+
1 row in set (0.00 sec)

select gender, group_concat(name, "_", age, " ", id), count(*) from studuent where gender = 1 group by gender;
+--------+---------------------------------------+----------+
| gender | group_concat(name, "_", age, " ", id) | count(*) |
+--------+---------------------------------------+----------+
| 男     | 小黃_17 2,十一_15 16,十二_18 17       |        3 |
+--------+---------------------------------------+----------+
1 row in set (0.00 sec)

# where是對原表的資料進行判斷
# having表示對分組進行條件判斷,是進行分組之後在判斷
# 查詢平均年年齡超過18歲的性別以及姓名  hanving avg(age)>18
select gender, group_concat(name) from studuent group by gender having avg(age)>8;
select gender, group_concat(name), avg(age), count(*) from studuent group by gender having count(*) > 3;
select gender, group_concat(name), avg(age) from studuent group by gender having avg(age) > 11;

#在GROUP BY子句中使用WITH ROLLUP
#使用WITH ROLLUP關鍵字之後,在所有查詢出的分組記錄之後增加一條記錄,該記錄計算查詢出的所有記錄的總和,即統計記錄數量。
select gender, group_concat(name), count(name) from studuent group by gender with rollup having avg(age)>8;
#由結果可以看到,通過GROUP BY分組之後,在顯示結果的最後面新添加了一行,該行Total列的值正好是上面所有數值之和。

6.2多欄位分組

使用GROUP BY可以對多個欄位進行分組,GROUP BY關鍵字後面跟需要分組的欄位,MySQL根據多欄位的值來進行層次分組,分組層次從左到右,即先按第1個欄位分組,然後在第1個欄位值相同的記錄中再根據第2個欄位的值進行分組,以此類推。

select gender, cls_id, group_concat(name, ' ', cls_id) from studuent group by gender, cls_id;


# GROUP BY和ORDER BY一起使用
# 某些情況下需要對分組進行排序,在前面的介紹中,ORDER BY用來對查詢的記錄排序,如果和GROUP BY一起使用可以完成對分組的排序。
select gender, group_concat(name, age, height) from studuent group by gender having avg(age)>8 order by count(height);
# GROUP BY子句按訂單號對資料進行分組,SUM()函式便可以返回總的訂單價格,HAVING子句對分組資料進行過濾,使得只返回總價格大於100的訂單,最後使用ORDER BY子句排序輸出。
# 當使用ROLLUP時,不能同時使用ORDER BY子句進行結果排序,即ROLLUP和ORDER BY是互相排斥的。

7 分頁查詢

limit start, count --直接限制查詢出來的個數
帶一個引數的LIMIT指定從查詢結果的首行開始,唯一的引數表示返回的行數,即“LIMIT n”與“LIMIT 0,n”等價。帶兩個引數的LIMIT可以返回從任何一個位置開始的指定的行數。返回第一行時,位置偏移量是0。因此,“LIMIT 1, 1”將返回第二行,而不是第一行。
MySQL 8.0中可以使用“LIMIT 4 OFFSET 3”,意思是獲取從第5條記錄開始後面的3條記錄,和“LIMIT 4,3;”返回的結果相同。

# 查詢前五個資料
select * from studuent limit 5;  # 只顯示前兩個
select * from studuent order by age desc limit 5;

# 限制查詢的個數
select * from studuent limit 7, 4;  # 開始第一個為0   規律:limit (第N頁-1)*每頁的個數, 每頁的個數;
#         +----+--------+------+--------+--------+--------+-----------+
#         | id | name   | age  | height | gender | cls_id | is_delete |
#         +----+--------+------+--------+--------+--------+-----------+
#         |  9 | 小一   |   10 | 188.00 | 女     |      9 |           |
#         | 10 | 小二   |   15 | 182.00 | 中性   |      9 |           |
#         | 11 | 小三   |   18 | 184.00 | 女     |      6 |           |
#         | 12 | 小四   |   19 | 185.00 | 保密   |      4 |           |
#         +----+--------+------+--------+--------+--------+-----------+
#         4 rows in set (0.00 sec)

# 注意:limit必須放在最後。
# 順序為where order by limit
select * from studuent where  gender = 2 order by height desc limit  0, 2

8連線查詢

連線查詢:即多個表之間進行關聯查詢

#inner join ... on on意味著條件
select * from studuent inner join classes;

select * from studuent inner join classes on studuent.cls_id = classes.id;   #找打相應的資訊顯示
#         +----+--------+------+--------+--------+--------+-----------+----+-------------+
#         | id | name   | age  | height | gender | cls_id | is_delete | id | name        |
#         +----+--------+------+--------+--------+--------+-----------+----+-------------+
#         |  1 | 小明   |   18 | 168.00 | 女     |      1 |           |  1 | python01期  |
#         |  2 | 小黃   |   17 | 175.00 | 男     |      2 |           |  2 | python02期  |
#         |  3 | 小紅   |   14 | 177.00 | 女     |      3 |           |  3 | python04期  |
#         | 13 | 小五   |   13 | 190.00 | 女     |      3 |           |  3 | python04期  |
#         | 17 | 十二   |   18 | 176.00 | 男     |      2 |           |  2 | python02期  |
#         +----+--------+------+--------+--------+--------+-----------+----+-------------+
#         5 rows in set (0.00 sec)


#     --按照要求現實姓名和年級
select studuent.* from studuent;
select classes.* from classes;
select studuent.*, classes.name  from studuent inner join classes on studuent.cls_id = classes.id;
#         +----+--------+------+--------+--------+--------+-----------+-------------+
#         | id | name   | age  | height | gender | cls_id | is_delete | name        |
#         +----+--------+------+--------+--------+--------+-----------+-------------+
#         |  1 | 小明   |   18 | 168.00 | 女     |      1 |           | python01期  |
#         |  2 | 小黃   |   17 | 175.00 | 男     |      2 |           | python02期  |
#         |  3 | 小紅   |   14 | 177.00 | 女     |      3 |           | python04期  |
#         | 13 | 小五   |   13 | 190.00 | 女     |      3 |           | python04期  |
#         | 17 | 十二   |   18 | 176.00 | 男     |      2 |           | python02期  |
#         +----+--------+------+--------+--------+--------+-----------+-------------+
#         5 rows in set (0.00 sec)

#     --簡寫重新命名
select s.*, c.name  from studuent as s inner join classes as c on s.cls_id = c.id;
#         +----+--------+------+--------+--------+--------+-----------+-------------+
#         | id | name   | age  | height | gender | cls_id | is_delete | name        |
#         +----+--------+------+--------+--------+--------+-----------+-------------+
#         |  1 | 小明   |   18 | 168.00 | 女     |      1 |           | python01期  |
#         |  2 | 小黃   |   17 | 175.00 | 男     |      2 |           | python02期  |
#         |  3 | 小紅   |   14 | 177.00 | 女     |      3 |           | python04期  |
#         | 13 | 小五   |   13 | 190.00 | 女     |      3 |           | python04期  |
#         | 17 | 十二   |   18 | 176.00 | 男     |      2 |           | python02期  |
#         +----+--------+------+--------+--------+--------+-----------+-------------+
#         5 rows in set (0.00 sec)


#     --加上排序
select s.*, c.name  from studuent as s inner join classes as c on s.cls_id = c.id order by c.name, s.id ;
#         +----+--------+------+--------+--------+--------+-----------+-------------+
#         | id | name   | age  | height | gender | cls_id | is_delete | name        |
#         +----+--------+------+--------+--------+--------+-----------+-------------+
#         |  1 | 小明   |   18 | 168.00 | 女     |      1 |           | python01期  |
#         | 17 | 十二   |   18 | 176.00 | 男     |      2 |           | python02期  |
#         |  2 | 小黃   |   17 | 175.00 | 男     |      2 |           | python02期  |
#         | 13 | 小五   |   13 | 190.00 | 女     |      3 |           | python04期  |
#         |  3 | 小紅   |   14 | 177.00 | 女     |      3 |           | python04期  |
#         +----+--------+------+--------+--------+--------+-----------+-------------+
#         5 rows in set (0.00 sec)


#     --更改顯示順序
select c.name, s.* from studuent as s inner join classes as c on s.cls_id = c.id order by c.name, s.id ;
#         +-------------+----+--------+------+--------+--------+--------+-----------+
#         | name        | id | name   | age  | height | gender | cls_id | is_delete |
#         +-------------+----+--------+------+--------+--------+--------+-----------+
#         | python01期  |  1 | 小明   |   18 | 168.00 | 女     |      1 |           |
#         | python02期  | 17 | 十二   |   18 | 176.00 | 男     |      2 |           |
#         | python02期  |  2 | 小黃   |   17 | 175.00 | 男     |      2 |           |
#         | python04期  | 13 | 小五   |   13 | 190.00 | 女     |      3 |           |
#         | python04期  |  3 | 小紅   |   14 | 177.00 | 女     |      3 |           |
#         +-------------+----+--------+------+--------+--------+--------+-----------+
#         5 rows in set (0.00 sec)

#     --多條件排序
select c.name, s.* from studuent as s inner join classes as c on s.cls_id = c.id order by c.name, s.id, s.age;
#         +-------------+----+--------+------+--------+--------+--------+-----------+
#         | name        | id | name   | age  | height | gender | cls_id | is_delete |
#         +-------------+----+--------+------+--------+--------+--------+-----------+
#         | python01期  |  1 | 小明   |   18 | 168.00 | 女     |      1 |           |
#         | python02期  |  2 | 小黃   |   17 | 175.00 | 男     |      2 |           |
#         | python02期  | 17 | 十二   |   18 | 176.00 | 男     |      2 |           |
#         | python04期  |  3 | 小紅   |   14 | 177.00 | 女     |      3 |           |
#         | python04期  | 13 | 小五   |   13 | 190.00 | 女     |      3 |           |
#         +-------------+----+--------+------+--------+--------+--------+-----------+
#         5 rows in set (0.00 sec)


# 2. 外連線查詢(分為左連線右連線)
#     --右連線查詢
#
#     --左連線查詢(那個表在左邊,以這個表為基準取查詢的資訊,取不出來莫認為Null)
select * from studuent as s left join classes as c on s.cls_id = c.id;
#         +----+--------+------+--------+--------+--------+-----------+------+-------------+
#         | id | name   | age  | height | gender | cls_id | is_delete | id   | name        |
#         +----+--------+------+--------+--------+--------+-----------+------+-------------+
#         |  1 | 小明   |   18 | 168.00 | 女     |      1 |           |    1 | python01期  |
#         |  2 | 小黃   |   17 | 175.00 | 男     |      2 |           |    2 | python02期  |
#         | 17 | 十二   |   18 | 176.00 | 男     |      2 |           |    2 | python02期  |
#         |  3 | 小紅   |   14 | 177.00 | 女     |      3 |           |    3 | python04期  |
#         | 13 | 小五   |   13 | 190.00 | 女     |      3 |           |    3 | python04期  |
#         |  4 | 小漢   |   11 | 180.00 | 中性   |      4 |           | NULL | NULL        |
#         |  5 | 小八   |   12 | 187.00 | 中性   |      5 |           | NULL | NULL        |
#         |  6 | 小九   |   13 | 182.00 | 保密   |      6 |           | NULL | NULL        |
#         |  7 | 小十   |   18 | 188.00 | 中性   |      7 |           | NULL | NULL        |
#         |  8 | 小之   |   17 | 186.00 | 女     |      8 |           | NULL | NULL        |
#         |  9 | 小一   |   10 | 188.00 | 女     |      9 |           | NULL | NULL        |
#         | 10 | 小二   |   15 | 182.00 | 中性   |      9 |           | NULL | NULL        |
#         | 11 | 小三   |   18 | 184.00 | 女     |      6 |           | NULL | NULL        |
#         | 12 | 小四   |   19 | 185.00 | 保密   |      4 |           | NULL | NULL        |
#         | 14 | 小六   |   14 | 189.00 | 女     |      4 |           | NULL | NULL        |
#         | 15 | 小七   |   15 | 178.00 | 女     |      5 |           | NULL | NULL        |
#         | 16 | 十一   |   15 | 167.00 | 男     |      7 |           | NULL | NULL        |
#         +----+--------+------+--------+--------+--------+-----------+------+-------------+
#         17 rows in set (0.00 sec)
#


#     --與inner join ... on比較
select * from studuent as s  inner join classes as c on s.cls_id = c.id;
#         +----+--------+------+--------+--------+--------+-----------+----+-------------+
#         | id | name   | age  | height | gender | cls_id | is_delete | id | name        |
#         +----+--------+------+--------+--------+--------+-----------+----+-------------+
#         |  1 | 小明   |   18 | 168.00 | 女     |      1 |           |  1 | python01期  |
#         |  2 | 小黃   |   17 | 175.00 | 男     |      2 |           |  2 | python02期  |
#         |  3 | 小紅   |   14 | 177.00 | 女     |      3 |           |  3 | python04期  |
#         | 13 | 小五   |   13 | 190.00 | 女     |      3 |           |  3 | python04期  |
#         | 17 | 十二   |   18 | 176.00 | 男     |      2 |           |  2 | python02期  |
#         +----+--------+------+--------+--------+--------+-----------+----+-------------+
#         5 rows in set (0.01 sec)
#
#
#     --left是指left左邊(等號左邊)的資料表
select * from studuent;
select * from classes as c left join studuent as s on c.id = s.cls_id;
#         +----+-------------+------+--------+------+--------+--------+--------+-----------+
#         | id | name        | id   | name   | age  | height | gender | cls_id | is_delete |
#         +----+-------------+------+--------+------+--------+--------+--------+-----------+
#         |  1 | python01期  |    1 | 小明   |   18 | 168.00 | 女     |      1 |           |
#         |  2 | python02期  |    2 | 小黃   |   17 | 175.00 | 男     |      2 |           |
#         |  3 | python04期  |    3 | 小紅   |   14 | 177.00 | 女     |      3 |           |
#         |  3 | python04期  |   13 | 小五   |   13 | 190.00 | 女     |      3 |           |
#         |  2 | python02期  |   17 | 十二   |   18 | 176.00 | 男     |      2 |           |
#         +----+-------------+------+--------+------+--------+--------+--------+-----------+
#         5 rows in set (0.00 sec)


#     --right join ... on 一般用的比較少  使用左連線調換兩個資料表的順序即可
#
#     --查詢沒有對應班級資訊的學生
#     --思路:對於查詢出的結果我們可以將其看作一個新的表,然後在此新表的基礎上進行再次操作查詢
#     --如果在原表裡面進行查詢使用where
#     --在查詢的基礎上進行再次操作使用having
select * from studuent as s left join classes as c on c.id = s.cls_id having c.id is NULL;
select * from studuent as s left join classes as c on c.id = s.cls_id where c.id is NULL; #這樣也行
#         +----+--------+------+--------+--------+--------+-----------+------+------+
#         | id | name   | age  | height | gender | cls_id | is_delete | id   | name |
#         +----+--------+------+--------+--------+--------+-----------+------+------+
#         |  4 | 小漢   |   11 | 180.00 | 中性   |      4 |           | NULL | NULL |
#         |  5 | 小八   |   12 | 187.00 | 中性   |      5 |           | NULL | NULL |
#         |  6 | 小九   |   13 | 182.00 | 保密   |      6 |           | NULL | NULL |
#         |  7 | 小十   |   18 | 188.00 | 中性   |      7 |           | NULL | NULL |
#         |  8 | 小之   |   17 | 186.00 | 女     |      8 |           | NULL | NULL |
#         |  9 | 小一   |   10 | 188.00 | 女     |      9 |           | NULL | NULL |
#         | 10 | 小二   |   15 | 182.00 | 中性   |      9 |           | NULL | NULL |
#         | 11 | 小三   |   18 | 184.00 | 女     |      6 |           | NULL | NULL |
#         | 12 | 小四   |   19 | 185.00 | 保密   |      4 |           | NULL | NULL |
#         | 14 | 小六   |   14 | 189.00 | 女     |      4 |           | NULL | NULL |
#         | 15 | 小七   |   15 | 178.00 | 女     |      5 |           | NULL | NULL |
#         | 16 | 十一   |   15 | 167.00 | 男     |      7 |           | NULL | NULL |
#         +----+--------+------+--------+--------+--------+-----------+------+------+
#         12 rows in set (0.00 sec)

9自關聯查詢

匯入areas.sql檔案中的資料,從areas.sql檔案目錄下登入資料庫,使用source areas.sql匯入資料。

一個表中的一列關聯到該表中的另一列:自關聯
#使用:省市關聯、行政關係等。

create table areas(
    aid int primary key,
    pid int,
    atitle varchar(20),
    types tinyint(1) default "2"
);


# 檢視省份
select * from areas where pid = 1;


# 檢視省份市的個數
select * from areas where atitle = '陝西';
    +-----+------+--------+-------+
    | aid | pid  | atitle | types |
    +-----+------+--------+-------+
    |  24 |    1 | 陝西   |     1 |
    +-----+------+--------+-------+
    1 row in set (0.00 sec)

select * from areas where pid = 24;
    +-----+------+--------+-------+
    | aid | pid  | atitle | types |
    +-----+------+--------+-------+
    | 311 |   24 | 西安   |     2 |
    | 312 |   24 | 安康   |     2 |
    | 313 |   24 | 寶雞   |     2 |
    | 314 |   24 | 漢中   |     2 |
    | 315 |   24 | 商洛   |     2 |
    | 316 |   24 | 銅川   |     2 |
    | 317 |   24 | 渭南   |     2 |
    | 318 |   24 | 咸陽   |     2 |
    | 319 |   24 | 延安   |     2 |
    | 320 |   24 | 榆林   |     2 |
    +-----+------+--------+-------+
    10 rows in set (0.00 sec)

select * from areas where pid = 311;
    +------+------+-----------+-------+
    | aid  | pid  | atitle    | types |
    +------+------+-----------+-------+
    | 2596 |  311 | 蓮湖區    |     3 |
    | 2597 |  311 | 新城區    |     3 |
    | 2598 |  311 | 碑林區    |     3 |
    | 2599 |  311 | 雁塔區    |     3 |
    | 2600 |  311 | 灞橋區    |     3 |
    | 2601 |  311 | 未央區    |     3 |
    | 2602 |  311 | 閻良區    |     3 |
    | 2603 |  311 | 臨潼區    |     3 |
    | 2604 |  311 | 長安區    |     3 |
    | 2605 |  311 | 藍田縣    |     3 |
    | 2606 |  311 | 周至縣    |     3 |
    | 2607 |  311 | 戶縣      |     3 |
    | 2608 |  311 | 高陵縣    |     3 |
    +------+------+-----------+-------+
    13 rows in set (0.01 sec)


# 另一種查詢方法(假如有兩章表的情況下,一張省份表,一張地級市表的情況下,地級市的pid = 省份表的aid)
# 思路:可以通過as生成新的表
select * from areas as province inner join areas as city on province.aid = city.pid having province.atitle = "陝西";
select province.atitle, city.atitle from areas as province inner join areas as city on city.pid = province.aid having province.atitle = "陝西";

    +-----+------+--------+-------+-----+------+--------+-------+
    | aid | pid  | atitle | types | aid | pid  | atitle | types |
    +-----+------+--------+-------+-----+------+--------+-------+
    |  24 |    1 | 陝西   |     1 | 311 |   24 | 西安   |     2 |
    |  24 |    1 | 陝西   |     1 | 312 |   24 | 安康   |     2 |
    |  24 |    1 | 陝西   |     1 | 313 |   24 | 寶雞   |     2 |
    |  24 |    1 | 陝西   |     1 | 314 |   24 | 漢中   |     2 |
    |  24 |    1 | 陝西   |     1 | 315 |   24 | 商洛   |     2 |
    |  24 |    1 | 陝西   |     1 | 316 |   24 | 銅川   |     2 |
    |  24 |    1 | 陝西   |     1 | 317 |   24 | 渭南   |     2 |
    |  24 |    1 | 陝西   |     1 | 318 |   24 | 咸陽   |     2 |
    |  24 |    1 | 陝西   |     1 | 319 |   24 | 延安   |     2 |
    |  24 |    1 | 陝西   |     1 | 320 |   24 | 榆林   |     2 |
    +-----+------+--------+-------+-----+------+--------+-------+
    10 rows in set (0.01 sec)


select * from areas as province inner join areas as city on city.pid = province.aid having province.atitle = "西安";
    +-----+------+--------+-------+------+------+-----------+-------+
    | aid | pid  | atitle | types | aid  | pid  | atitle    | types |
    +-----+------+--------+-------+------+------+-----------+-------+
    | 311 |   24 | 西安   |     2 | 2596 |  311 | 蓮湖區    |     3 |
    | 311 |   24 | 西安   |     2 | 2597 |  311 | 新城區    |     3 |
    | 311 |   24 | 西安   |     2 | 2598 |  311 | 碑林區    |     3 |
    | 311 |   24 | 西安   |     2 | 2599 |  311 | 雁塔區    |     3 |
    | 311 |   24 | 西安   |     2 | 2600 |  311 | 灞橋區    |     3 |
    | 311 |   24 | 西安   |     2 | 2601 |  311 | 未央區    |     3 |
    | 311 |   24 | 西安   |     2 | 2602 |  311 | 閻良區    |     3 |
    | 311 |   24 | 西安   |     2 | 2603 |  311 | 臨潼區    |     3 |
    | 311 |   24 | 西安   |     2 | 2604 |  311 | 長安區    |     3 |
    | 311 |   24 | 西安   |     2 | 2605 |  311 | 藍田縣    |     3 |
    | 311 |   24 | 西安   |     2 | 2606 |  311 | 周至縣    |     3 |
    | 311 |   24 | 西安   |     2 | 2607 |  311 | 戶縣      |     3 |
    | 311 |   24 | 西安   |     2 | 2608 |  311 | 高陵縣    |     3 |
    +-----+------+--------+-------+------+------+-----------+-------+
    13 rows in set (0.01 sec)

10子查詢

簡單來講,子查詢就是一個select中嵌套了一個select,子查詢效率比較低。

--查詢身高最高的男生
select max(height) from studuent;
+-------------+
| max(height) |
+-------------+
|      190.00 |
+-------------+
1 row in set (0.00 sec)

select * from studuent where height = (select max(height) from studuent);
+----+--------+------+--------+--------+--------+-----------+
| id | name   | age  | height | gender | cls_id | is_delete |
+----+--------+------+--------+--------+--------+-----------+
| 13 | 小五   |   13 | 190.00 | 女     |      3 |           |
+----+--------+------+--------+--------+--------+-----------+
1 row in set (0.00 sec)

--利用子查詢解決自關聯查詢中的問題
select * from areas where pid = (select aid from areas where atitle = "陝西");
    +-----+------+--------+-------+
    | aid | pid  | atitle | types |
    +-----+------+--------+-------+
    | 311 |   24 | 西安   |     2 |
    | 312 |   24 | 安康   |     2 |
    | 313 |   24 | 寶雞   |     2 |
    | 314 |   24 | 漢中   |     2 |
    | 315 |   24 | 商洛   |     2 |
    | 316 |   24 | 銅川   |     2 |
    | 317 |   24 | 渭南   |     2 |
    | 318 |   24 | 咸陽   |     2 |
    | 319 |   24 | 延安   |     2 |
    | 320 |   24 | 榆林   |     2 |
    +-----+------+--------+-------+
    10 rows in set (0.00 sec)

MySQL視訊

學習視訊

arears.sql檔案

areas.sql檔案