1. 程式人生 > 實用技巧 >MySQl筆記--多表查詢

MySQl筆記--多表查詢

多表查詢

/**
  多表查詢
  一次查詢多張表
 */

show databases;
use db_26;


show tables;

create table student
(
    sid   int primary key,
    sname varchar(11),
    sex   char(1),
    sage  int,
    scid  int,
    constraint fk_s_c foreign key (scid) references class (cid)
    # 設定外來鍵
);

create table class
(
    cid     int primary key,
    cname   varchar(11),
    cbanxun varchar(50)
);


insert into class (cid, cname, cbanxun)
values (1, '鄭州1期', '天道酬勤'),
       (2, 'bigdata期', '不忘初衷'),
       (3, 'python期', '好好學習'),
       (4, 'html期', '天天向上'),
       (5, 'vr期', '做個有錢人');


alter table student
    modify sid int auto_increment;

insert into student (sid, sname, sex, sage, scid)
values (null, '張三', if(rand() > 0.5, '男', '女'), truncate(rand() * 10 + 15, 0), truncate(rand() * 4 + 1, 0));

insert into student (sid, sname, sex, sage, scid)
values (null, '張四', if(rand() > 0.5, '男', '女'), null, truncate(rand() * 4 + 1, 0));


select *
from student;



/**
  多表查詢1
  合併結果集 :把兩個 select 的結果合併為一個結果
  格式:select union select2  | select1 union all select2
  區別: union 去重              union all 不去重
 */

# 獲取所有男生的名字、性別、編號
select sname, sex, sid
from student
where sex = '男';

select sname, sex, sid
from student
where sex = '女';

# 獲取男生和女生的姓名、性別、編號
select sname, sex, sid
from student
where sex = '男'
union all
# 合併結果集
select sname, sex, sid
from student
where sex = '女';

# 獲取男生和女生的名字,去重
select sname
from student
where sex = '男'
union
# 去重
# 合併結果集
select sname
from student
where sex = '女';

# 獲取男生和女生的名字,不去重
select sname
from student
where sex = '男'
union
# 不去重
# 合併結果集
select sname
from student
where sex = '女';


/**
  多表查詢 2:連線查詢
  定義: 一次查多張表
  笛卡爾積:讓所有的表見一次面
  語法: select 列|聚合函式  from 表1,表2  where 條件;
  去除垃圾行:主表的主鍵值 = 從表的外來鍵值 來找到兩條有關係的記錄

  內連線:只顯示滿足條件的記錄,兩個表都不完整
    方言格式 select 列|聚合函式  from 表1,表2  where 條件;
    標準格式 select 列|聚合函式  from 表1 inner join 表2  on 條件;

  外連線:保持一邊表的完整性
    左外連線:select 列|聚合函式  from 表1 left join 表2  on 條件;
    右外連線:select 列|聚合函式  from 表1 right join 表2  on 條件;
 */

# 笛卡爾積 所有資料 方言
select *
from student as s1,
     class as c1;

# 笛卡爾積 去除垃圾行 方言
select *
from student as s1,
     class as c1
where c1.cid = s1.scid
order by s1.sid;

# 笛卡爾積 去除垃圾行 標準格式
select *
from student as s1
         inner join
     class as c1
     on c1.cid = s1.scid;

# 左連線 獲取所有的學生和其班級的資訊
select *
from student s1
         left join class c
                   on s1.scid = c.cid;

# 右連線 獲取學生和所有班級的資訊
select *
from student s1
         right join class c
                    on s1.scid = c.cid;


/**
  多表查詢3:子查詢 select 中巢狀 select
  子查詢的 select 所處的
  位置1: where 後面作為條件,
            單行多列 運算子 = >= <= < != ,
            單行多列: = != ,
            多行單列 [=|!=|>|<|>=|<=] any 、[=|>|<|!=] all 、in、not in
            多行多列 [in | not in] 、[!=all]、 [ = any]
  位置2:form 後面作為基表來查詢
 */

# 獲取年齡最大的學生的資訊
select *
from student
where sage = MAX(sage);
# where 不能加 聚合函式

# 獲取年齡最大的學生的資訊
select *
from student
where sage = (select max(sage) from student);

# 獲取年齡大於 7 號學生年齡的學生
select *
from student
where sage > (select sage from student where sid = 7);


# 獲取和3相同年齡、相同性別的所有學生的資訊
select *
from student
where sage = (select sage from student where sid = 3)
  and sex = (select sex from student where sid = 3);

# 或者
select *
from student
where (sage, sex) = (select sage, sex from student where sid = 3);


# 獲取年齡最大的學生的資訊
# 使用連線查詢
select *
from student s
         join
         (select MAX(sage) m from student) ms
         on s.sage = ms.m;

# 獲取和1班學生相同年齡的其他班級的學生的資訊
# 獲取 1 班的年齡
select sage
from student
where scid = 1;
# 使用 in 或者 = any
select *
from student
where sid != 1
  and sage in (select sage from student where scid = 1);


# 獲取和1班學生年齡不同的其他班級的學生的資訊
select *
from student
where sid != 1
  and sage not in (select sage from student where scid = 1);

# 獲取和2班學生年齡都大的其他班級的學生的資訊
select *
from student
where sid != 2
  and sage > all (select sage from student where scid = 2);

# 獲取和1班學生年齡都小的其他班級的學生的資訊
select *
from student
where sid != 1
  and sage < all (select sage from student where scid = 1);



# 多行多列
# 獲取1班學生年齡和性別相同的其他班級學生的資訊
select *
from student
where (sage, sex) = any (select sage, sex from student where scid = 1)
  #可以使用 [= any | in | not in | !=all]
  and scid != 1;


# 獲取和 1 班學生,相同年齡和性別 的其他班級的學生的資訊

select *
from student s
         join
         (select * from student where scid = 1) s3
         on s.sage = s3.sage
             and s.sex = s3.sex
             and s.scid != 3;

# 獲取每個班級的資訊,以及最大年齡
select *, (select max(sage) from student where scid = class.cid) '最大年齡'
from class;

# 最大年齡 和 cid =1
select *, (select max(sage) from student where scid = class.cid) '最大年齡'
from class
where cid = 1;

# 所有學生的資訊,及其最大年齡的差距

select *
from student;
# 所有學生

select max(sage)
from student;
# 最大年齡

select *,
       (select max(sage) from student)                     '最大年齡',
       abs(student.sage - (select max(sage) from student)) '差距'
from student;