Mysql多表查詢練習

-- 多表設計 `student, teacher, course`
-- 教師表
create table teacher(
    id int primary key auto_increment,
    name varchar(20)
);

-- 學生表
create table student(
    id int primary key auto_increment,
    name varchar(20),
    city varchar(20),
    age int
);
-- 課程表
create table course(
    id int primary key auto_increment,
    name varchar(20),
    teacher_id int,
    foreign key (teacher_id) references teacher(id)
);
-- 中間表
create table student_course(
    student_id int,
    course_id int,
    score int,
    foreign key (student_id) references student(id),
    foreign key (course_id) references course(id) 
);

insert into teacher values(null,'胡歌');
insert into teacher values(null,'韓雪');
insert into teacher values(null,'李梅梅');

insert into student values(null,'小王','北京',20);
insert into student values(null,'小李','上海',18);
insert into student values(null,'小周','北京',22);
insert into student values(null,'小劉','北京',21);
insert into student values(null,'小張','上海',22);
insert into student values(null,'小趙','北京',17);
insert into student values(null,'小蔣','上海',23);
insert into student values(null,'小韓','北京',25);
insert into student values(null,'小魏','上海',25);
insert into student values(null,'小明','北京',20);

insert into course values(null,'語文',1);
insert into course values(null,'數學',1);
insert into course values(null,'生物',2);
insert into course values(null,'化學',2);
insert into course values(null,'物理',2);
insert into course values(null,'英語',3);

insert into student_course values(1,1,80);
insert into student_course values(1,2,90);
insert into student_course values(1,3,85);
insert into student_course values(1,4,78);
insert into student_course values(2,2,53);
insert into student_course values(2,3,77);
insert into student_course values(2,5,80);
insert into student_course values(3,1,71);
insert into student_course values(3,2,70);
insert into student_course values(3,4,80);
insert into student_course values(3,5,65);
insert into student_course values(3,6,75);
insert into student_course values(4,2,90);
insert into student_course values(4,3,80);
insert into student_course values(4,4,70);
insert into student_course values(4,6,95);
insert into student_course values(5,1,60);
insert into student_course values(5,2,70);
insert into student_course values(5,5,80);
insert into student_course values(5,6,69);
insert into student_course values(6,1,76);
insert into student_course values(6,2,88);
insert into student_course values(6,3,87);
insert into student_course values(7,4,80);
insert into student_course values(8,2,71);
insert into student_course values(8,3,58);
insert into student_course values(8,5,68);
insert into student_course values(9,2,88);
insert into student_course values(10,1,77);
insert into student_course values(10,2,76);
insert into student_course values(10,3,80);
insert into student_course values(10,4,85);
insert into student_course values(10,5,83);


# 多表查詢

create table A(
  id int primary key auto_increment,
  name varchar(20) not null
);
insert into A values(1,'蘋果');
insert into A values(2,'橘子');
insert into A values(3,'香蕉');

create table B( 
   id int primary key auto_increment,
   price double
);
insert into B values(1,2.30);
insert into B values(2,3.50);
insert into B values(4,null);

-- 只查詢水果表
select * from a;

-- 只查詢價格表
select * from b;

-- 笛卡爾積
select * from a,b where a.id = b.id;-- 隱式內連接


-- 內連接: select * from 表名a inner join 表b on 條件
select * from a INNER JOIN b on a.id = b.id
select * from a inner join b on a.id = b.id;-- 顯示內連接

-- 外連接
-- 1. 左外連接: select * from 表a left outer join 表b on 條件

-- 需求 : 列出所有的水果的信息和價格
select * from b left outer join a on a.id = b.id;
SELECT * from a left  join b on a.id = b.id;

-- 2. 右外連接: select * from 表a right outer join 表b on 條件

-- 需求 : 列出所有的價格信息和水果
select * from a right outer join b on a.id = b.id;

select * from b left outer join a on a.id = b.id;

-- 3. 全外連接  select * from 表a full outer join 表b on 條件
-- 需求 : 查詢所有的水果的信息,和價格的信息

select * from a full outer join b on a.id = b.id;-- mysql不支持這種寫法而已

-- mysql的全外連接如何實現
-- 左外連接聯合右外連接
select * from a left outer join b on a.id = b.id
union    -- union只顯示不重複的數據,union all,將所有的數據都展示
select * from a right outer join b on a.id = b.id;

 


# 關聯子查詢
-- 需求 : 查詢年齡最大的學生信息

-- 查詢出最大的年齡
SELECT * from student 
        where age IN(SELECT max(age) from student)

select max(age) from student;-- 25

-- 查詢年齡爲25歲的學生的信息
select * from student where age = 25;
SELECT * from student where age  in(25);
select * from student 
     where age = (select max(age) from student);
 

-- -- in 的用法 :
-- 需求:查詢分數不及格的所有的學生信息
SELECT * FROM student where student.id in(select student_id from student_course where score < 60)
-- 從中間表中,查詢出不及格的學生的id
select student_id FROM student_course WHERE score<60;

select student_id from student_course where score < 60;
-- 從學生表中,查詢對應id的學生信息

-- in:當查詢條件是多個,或者不確定時,要使用in
select * from student 
    where id in (select student_id from student_course where score < 60);

 


-- all 的用法 :
-- 需求 : 查詢年齡最大的學生的信息
SELECT * from student where age in(SELECT max(age) from student)
SELECT * from student where id in(SELECT id from student where age in(SELECT MAX(age) from student ) )
SELECT * from student where age >=all(SELECT age from student)
-- 先查詢出所有的學生的年齡
select age from student

-- 只要>=所有年齡就是要找最大年齡
select * from student where age >= all(select age from student);
-- all()中只能放sql語句不能直接放值
select * from student where age >= all(18,22,25);-- 錯誤

 

-- any 和 some 的用法 :
-- 查詢成績是90的學生的信息
SELECT * from student where id in(SELECT student_course.student_id from student_course where student_course.score=90)
SELECT * from student where id = SOME(SELECT student_course.student_id from student_course where student_course.score=90)
SELECT * from student where id = ANY(SELECT student_course.student_id from student_course where student_course.score=90)
-- 從中間表中查詢90分的學生id
select student_id from student_course where score = 90;

-- 從學生表中查詢信息
select * from student 
    where id in (select student_id from student_course where score = 90);
    
-- 如果查詢結果是多個或不確定時,但是我就想用= 怎麼辦??
select * from student 
    where id = some(select student_id from student_course where score = 90);
    
select * from student 
    where id = any(select student_id from student_course where score = 90);
    
    
    
    -- as 定義 `臨時表`
-- 需求 : 查詢不及格的學生信息和不及格分數
select student.*,score from student,(SELECT * from student_course WHERE student_course.score<60) as temp where student.id = temp.student_id;
select student.*,temp.* from student,(SELECT * from student_course WHERE student_course.score<60) as temp where student.id = temp.student_id;

SELECT * FROM student,(SELECT student_course.student_id,student_course.score from student_course where student_course.score <60) as temp  where student.id = temp.student_id;
-- 從中間表中查詢不及格的學生的id和分數
    select student_id,score from student_course where score < 60;
-- 將上面的子查詢認作是一張臨時表as
    select student.*,score from student,
            (select student_id,score from student_course where score < 60) as temp
                where temp.student_id = student.id;

 

-- 子查詢練習
-- 需求 : 查詢數學成績比語文成績高的所有學生信息
select * from student_course where course_id in (SELECT id from course where `name` ='語文')
select * from student_course where course_id in (SELECT id from course where `name` ='數學')

SELECT * FROM student where id  in(
SELECT temp_chinese.student_id 
                from  
                (select * from student_course where course_id in (SELECT id from course where `name` ='語文')) as temp_chinese,
                (select * from student_course where course_id in (SELECT id from course where `name` ='數學')) as temp_maths
                where temp_chinese.student_id = temp_maths.student_id AND temp_maths.score>temp_chinese.score);
 
 
 
-- 1.1從課程表中查詢出數學的id
select id  from course where name = '數學';

-- 1.2從課程表中查詢出語文的id
select id  from course where name = '語文';

-- 2.1 從中間表中查詢數學成績
select student_id,score from student_course 
    where course_id = (select id  from course where name = '數學');

-- 2.2 從中間表中查詢語文成績
select student_id,score from student_course 
    where course_id = (select id  from course where name = '語文');

-- 3.從2個臨時表中進行內連接查詢獲取學生的id

select temp_math.student_id from 
    (
    select student_id,score from student_course 
    where course_id = (select id  from course where name = '數學')
    ) as temp_math,
    (
    select student_id,score from student_course 
    where course_id = (select id  from course where name = '語文')
    ) as temp_chinese
        where temp_math.student_id = temp_chinese.student_id 
            and temp_math.score > temp_chinese.score;


-- 4.從學生表中查詢出(1,5,6)的學生信息
    select * from student 
        where id in(
                select temp_math.student_id from 
            (
            select student_id,score from student_course 
            where course_id = (select id  from course where name = '數學')
            ) as temp_math,
            (
            select student_id,score from student_course 
            where course_id = (select id  from course where name = '語文')
            ) as temp_chinese
                where temp_math.student_id = temp_chinese.student_id 
                    and temp_math.score > temp_chinese.score
                    );

 

 


-- mysql 自帶函數 (知道即可)
-- 加密方法  *23AE809DDACAF96AF0FD78ED04B6A265E05AA257
select password('123');
select password("1111")
-- 字符方法
select ucase('itheima');
select lcase('ITHEIMA');
-- java 0基   sql 1基
select substring('王思聰',2,2);
-- 數字方法
select abs(-5);
select ceil(3.14);
select floor(3.14);

-- 日期方法
select now();
select current_date();
select current_time();

#  sql 強化練習

-- 1    查詢平均成績大於70分的同學的學號和平均成績
SELECT student_id,AVG(score)  as `平均成績`
    FROM student_course 
    GROUP BY student_id 
    HAVING AVG(score)>70;
    
    select student_id,avg(score) as 平均成績 from student_course 
        group by student_id
            having avg(score) > 70;

-- 2    查詢所有同學的學號、姓名、選課數、總成績
SELECT student.id  as '學號' ,student.`name` as '姓名', temp.選課數,temp.總成績 
    from student ,(
        SELECT student_id,sum(score) as '總成績',COUNT(score) as '選課數' 
            FROM student_course 
                GROUP BY student_id) as temp
                    where student.id = temp.student_id;


-- 2.1 從中間表中按學號分組查詢出學號、選課數、總成績
    select student_id,count(*),sum(score) 
        from student_course group by student_id;
        
-- 2.2 臨時表和學生表內連接查詢
-- 子查詢中的聚合函數不能直接使用!!!必須通過別名來使用
select student.id,student.name,temp.選課數,temp.總成績 from student,
    (
        select student_id,count(*) as 選課數,sum(score) as 總成績
        from student_course group by student_id
    ) as temp
        where temp.student_id = student.id;
        
        
        
        
-- 3    查詢學過趙雲老師所教課的同學的學號、姓名
SELECT *  from student where student.id in
    (SELECT student_id FROM student_course where student_course.course_id in(
        SELECT id from course where course.teacher_id in 
            (SELECT  id from teacher where teacher.name='趙雲')));
        
SELECT * from student_course where 
-- 3.1 查詢趙雲的id
    select id from teacher where name = '趙雲';
-- 3.2 從課程表中查詢趙雲所教的課程id
    select id from course 
        where teacher_id = (select id from teacher where name = '趙雲');
-- 3.3 從中間表查詢學過趙雲老師課程的學生id
    select student_id from student_course 
        where course_id in (
            select id from course 
                where teacher_id = (select id from teacher where name = '趙雲')
                            );
                            
-- 3.4從學生表中查詢上面的學號的姓名即可
    select * from student where id in (
            select student_id from student_course 
                where course_id in (
                    select id from course 
                        where teacher_id = (select id from teacher where name = '趙雲')
                            )
                                      );


-- 4    查詢沒學過關羽老師課的同學的學號、姓名
   SELECT * from student where student.id not in(
         SELECT DISTINCT(student_id) FROM student_course where course_id in(
             SELECT id from course where teacher_id =(
                    select id from teacher where name ="關羽")));

-- 4.1 查詢出學過關羽老師課的同學的學號、姓名
-- 4.2 取反
    select * from student where not id in (
            select student_id from student_course 
                where course_id in (
                    select id from course 
                        where teacher_id = (select id from teacher where name = '關羽')
                            )
                                      );
        
    -- 5    查詢學三門課以下的同學的學號、姓名
    select id as '學號' ,name as '姓名'  from student where id in
    (SELECT student_id from  student_course   GROUP BY student_id
    HAVING COUNT(course_id)>3 ORDER BY student_id ASC);
-- 5.1 從中間表按學號分組查詢 學號和選課數,條件:三門以下
select student_id ,count(*) from student_course 
        group by student_id having count(*) < 3;
-- 5.2 多表查詢內連接
    select student.id,student.name from student,
            (
        select student_id ,count(*) from student_course 
            group by student_id having count(*) < 3
            ) as temp
                where temp.student_id = student.id;

-- 6    查詢各科成績最高和最低的分
    SELECT course_id,MAX(score),MIN(score)
            FROM 
                student_course GROUP BY course_id;
                
    select course_id,max(score),min(score) 
            from 
                student_course group by course_id;

-- 7    查詢各個城市的學生數量
  SELECT city , COUNT(*) FROM student GROUP BY city;
    select city , count(*) from student group by city;
 
-- 8    查詢不及格的學生信息和課程信息
SELECT student.*,course.* from student,course ,
    (SELECT * from student_course where score<60) as temp
        where student.id = temp.student_id 
            and temp.course_id = course.id ; 
-- 8.1 從中間表查詢不及格的學生id,課程id
    select student_id , course_id from student_course
        where score < 60;
-- 8.2 3表聯查
select student.*,course.* from student,course,
    (
    select student_id , course_id from student_course
        where score < 60
    ) as temp
        where temp.student_id = student.id
            and temp.course_id = course.id;

-- 9    統計每門課程的學生選修人數(超過四人的進行統計)

select course_id,count(*) as 選修人數 from student_course          
group by course_id having 選修人數 > 4;


    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章