單表查詢進階與多表查詢

單表操做

分組查詢

group by

分組指的是將全部記錄按照某個相同的字段進行分類,好比針對員工信息表的職位分組,或者按照性別進行分組。sql

用法:運維

select 聚合函數,選取的字段 from 表名 group by 分組的字段函數

group by:是分組的關鍵字,必須和聚合函數一塊兒出現ui

where 條件語句和 group by 分組語句的前後順序設計

​ where > group by > havingcode

聚合函數有:排序

  • count:求數量
  • sum:求和
  • max:求最大數
  • min:求最小數
  • avg:求平均數

例子:索引

查詢表中全部記錄:內存

mysql> select * from userinfo;
+----+----------+-----+-----------+---------+
| id | name     | age | sarlay    | job     |
+----+----------+-----+-----------+---------+
|  1 | qinyj    |  18 |      0.00 | student |
|  2 | tank     |  18 |  10000.11 | teacher |
|  3 | jack     |  33 |  10000.33 | teacher |
|  4 | jing     |  20 |      1.33 | null    |
|  5 | xxx      |  20 | 100000.33 | teacher |
|  6 | xxx      |  20 |   1000.33 | teacher |
|  7 | xxx      |  20 | 100000.00 | teacher |
|  8 | xxx      |  20 |  10000.00 | teacher |
|  9 | jinggggg |  20 |  10000.00 | teacher |
+----+----------+-----+-----------+---------+
9 rows in set (0.00 sec)
  • 以職業爲例進行分組,統計一下teacher和student有多少人
select job,count(*) from userinfo group by job;

select job,count(*) as count from userinfo group by job;
  • 對職業進行分組,求出每一個職業中年齡最大的那我的
select name,max(age) from userinfo group by job;

select name,job,max(age) from userinfo group by job;
  • 求出每一個職業中最小年齡的人

select name,job,min(age) from userinfo group by job;

  • 求出每一個職業中的年齡總和

select job,sum(age) from userinfo group by job;

  • 求出每一個職業中的年齡平均數

select job,avg(age) from userinfo group by job;

having

表示對group by 以後的數據,進行二次篩選

  • 求出每一個職業中年齡平均數超過30歲的

select job,avg(age) from userinfo group by job having avg(age) > 20;

升序降序

order by

用法:order by 字段名 asc(升序) desc(降序)

  • 對年齡降序排序

select * from userinfo order by age desc;

  • 對id升序排序

select * from userinfo order by id;

  • 若是對多個字段進行排序,aes,desc:表示先對前者字段進行升序,若是前者字段有相同的行,再對後者字段降序

limit

分頁處理

用法:limit offset, size

offset:行數據索引

size:取多少條數據

  • 取5條數據

select * from userinfo limit 0,5;

  • 取第一條數據

select * from userinfo limit 1;

  • 取最後一條數據

select * from userinfo limit 9;

  • 若是不知道有多少行取還最後一條數據

select * from pymysql_test order by id desc limit 1;

總結

單表查詢關鍵字使用順序:

select * from 表名
    where 條件
    group by 條件
    having 條件
    order by 條件
    limit 條件;
    
where > group by > having > order by > limit

多表操做

什麼是外鍵

外鍵即一個表的字段關聯另外一個表的字段

爲何要使用外鍵

一、 減小內存佔用的空間

二、 方便修改,只須要修改一張表,其餘的表也會跟着修改

外鍵建立方法:

constraint 外鍵名 foreign key (被約束的字段) references 約束的表(約束的字段)

使用外鍵的三種關係

一對多

一對多的關係 即 員工--部門

一個部門能夠有多個員工

一個員工隸屬於一個部門

咱們拆分出來兩張表:部門表和員工表,那麼其中確定要一種關係將兩個表聯繫起來,那麼這個關係就是員工隸屬於部門的關係,就須要在員工表中標明是屬於哪一個部門的

先建立部門表

# 建立部門表
create table department(
    id int auto_increment primary key,
    name varchar(32) not null default ''
)charset=utf8;



# 插入部門表數據
insert into department (name) values ("運維部"),("財務部"),("研發部"),("行政部");

select * from department;
# 建立員工表
create table user(
    id int auto_increment primary key,
    name varchar(32) not null default ''
    depart_id int not null default 1,   # 建立外鍵字段
    
    constraint user_depart foreign key(depart_id) references department(id) # 關聯部門表
)charset=utf8;

# 插入員工表數據
insert into user (name,depart_id) values ("qinyj",1);
insert into user (name,depart_id) values ("qinyj2",2);
insert into user (name,depart_id) values ("qinyj3",3);
insert into user (name,depart_id) values ("qinyj4",4);
insert into user (name,depart_id) values ("qinyj5",1);

# 一個部門能夠有多個員工,若是在外鍵插入不存在的部門id則會報錯
insert into user (name,depart_id) values ("qiny6",5);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`school`.`user`, CONSTRAINT `user_depart` FOREIGN KEY (`depart_id`) REFERENCES `department` (`id`))

多對多

多對多的關係 即 相親系統,男孩和女孩約會

一個女嘉賓能夠和多個男嘉賓約會

一個男嘉賓能夠和多個女嘉賓約會

咱們拆分出來兩張表:男嘉賓表和女嘉賓表,那麼其中確定要一種關係將兩個表聯繫起來,那麼這個關係就是男女嘉賓約會的信息的關係,就須要來記錄這麼個東西,那麼這個信息在哪一個表中記錄?

咱們能夠再建立出來一個表,存放約會信息

# 建立男嘉賓表
create table boy(
    id int auto_increment primary key,
    boy_name varchar(32) not null default ''
)charset=utf8;


# 插入男嘉賓數據
insert into boy (boy_name) values ("張三"), ("李四"), ("老王");
# 建立女嘉賓表
create table girl(
    id int auto_increment primary key,
    girl_name varchar(32) not null default ''
)charset=utf8;

# 插入女嘉賓數據
insert into girl (girl_name) values ("麗麗"),("翠花"),("小紅");
# 建立約會信息表
create table b_g_info(
    id int auto_increment primary key,
    boy_id int not null default 1,
    girl_id int not null default 1,
    
    # 建立約會對應信息
    constraint b_g_info_boy foreign key(boy_id) references boy(id), # 關聯男嘉賓id
    constraint b_g_info_girl foreign key(girl_id) references girl(id)   # 關聯女嘉賓id
)charset=utf8;

# 插入約會信息數據
insert into b_g_info (boy_id,girl_id) values (1,1),(1,2),(2,2),(2,3);

一對一

一對一的關係 即 人--薪資

一我的有薪資

薪資屬於一我的

薪資屬於隱私信息,能夠寫在一張表中,可是隱私信息若是某人去查這我的的信息的話,薪資也會查出來,就會看到這個隱私信息,那麼咱們爲了隱藏這個所以數據,咱們能夠使用另外一張表來保存薪資

user表:
id name

薪資信息是比較敏感的字段,咱們須要將此字段單獨拆出來,變成一張獨立的表priv

priv表:
id salary uid (外鍵 + unique)

# 建立用戶表:
create table usertable(
    id int auto_increment primary key,
    name varchar(32) not null default ''
)charset=utf8;


# 插入用戶數據
insert into usertable (name) values ("張三"),("李四"),("老王");
# 建立薪資表
create table privtable(
    id int auto_increment primary key,
    salary int not null default 0,
    uid int unique not null default 1,
    constraint privt_user foreign key (uid) references usertable(id)
)charset=utf8;

# 插入薪資數據
insert into privtable (salary,uid) values (2000,1),(3000,2),(4000,3);

多表聯查

  • left join ... on ...
  • right join ... on ...
  • inner join ... on ...

咱們按照以上的關係分紅了多個表以後,那麼咱們如何去查詢數據呢?

設計到多個表的查詢咱們能夠使用left join

例子(兩表查詢):

mysql> select * from department;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | 運維部    |
|  2 | 財務部    |
|  3 | 研發部    |
|  4 | 行政部    |
+----+-----------+
4 rows in set (0.00 sec)

mysql> select * from user;
+----+--------+-----------+
| id | name   | depart_id |
+----+--------+-----------+
|  1 | qinyj  |         1 |
|  2 | qinyj2 |         2 |
|  3 | qinyj3 |         3 |
|  4 | qinyj4 |         4 |
|  5 | qinyj5 |         1 |
+----+--------+-----------+
5 rows in set (0.00 sec)
  • left join ... on ... 查詢員工名稱和隸屬的部門
select * from department 
    left join user on department.id=depart_id;

select user.name,department.name from department 
    left join user on department.id=depart_id;

select user.name,department.name from department 
    left join user on department.id=depart_id 
    where user.name="qinyj4";
  • right join ... on ... 基本和left join ... on ...使用方式同樣
  • inner join ... on ... 基本和left join ... on ...使用方式同樣

例子(三表/多表查詢):

mysql> select * from boy;
+----+----------+
| id | boy_name |
+----+----------+
|  1 | 張三     |
|  2 | 李四     |
|  3 | 老王     |
+----+----------+
3 rows in set (0.00 sec)

mysql> select * from girl;
+----+-----------+
| id | girl_name |
+----+-----------+
|  1 | 麗麗      |
|  2 | 翠花      |
|  3 | 小紅      |
+----+-----------+
3 rows in set (0.00 sec)

mysql> select * from b_g_info;
+----+--------+---------+
| id | boy_id | girl_id |
+----+--------+---------+
|  1 |      1 |       1 |
|  2 |      1 |       2 |
|  3 |      2 |       2 |
|  4 |      2 |       3 |
+----+--------+---------+
4 rows in set (0.00 sec)
  • 查詢男女嘉賓約會的姓名
select * from b_g_info 
    left join boy on b_g_info.boy_id=boy.id 
    left join girl on b_g_info.girl_id=girl.id;
    
    
select boy_name,girl_name from b_g_info 
    left join boy on b_g_info.boy_id=boy.id 
    left join girl on b_g_info.girl_id=girl.id;
相關文章
相關標籤/搜索