mysql練習案例(實操)


最近想要在回去復習mysql語句,就在網上找了一些案例練習,起初找得都是零零散散的,后面參考這篇博客做出了一個實操案例。Eric_Squirrelmysql學生表經典案例50題。

首先是建表,我用的是mysql5.7,基本上沒有問題

建庫

創建alibaba數據庫

create database alibaba;

切換到alibaba數據庫

use alibaba;

建表

創建學生表student表=

create table student(s_id varchar(10),s_name varchar(10),s_age date,s_sex varchar(10)) engine=InnoDB default charset utf8;
insert into student(s_id,s_name,s_age,s_sex)
values('01' , '趙雷', '1990-01-01' , ''),
('02' , '錢電' , '1990-12-21' , '')
,('03' , '孫風' , '1990-05-20' , '')
,('04' , '李雲' , '1990-08-06' , '')
,('05' , '周梅' , '1991-12-01' , '')
,('06' , '吳蘭' , '1992-03-01' , '')
,('07' , '鄭竹' , '1989-07-01' , '')
,('08' , '王菊' , '1990-01-20' , '');

查詢 student 表中的數據

select * from student;

創建課程表course

create table course(c_id varchar(10),c_name varchar(10),t_id varchar(10)) engine=InnoDB default charset utf8;
insert into course values('01' , '語文' , '02'),
('02' , '數學' , '01'),
('03' , '英語' , '03');

查詢 course 表中的數據

select * from course;

創建教師表teacher

create table teacher(t_id varchar(10),t_name varchar(10)) engine=InnoDB default charset utf8;
insert into teacher values('01' , '張三'),('02' , '李四'),('03' , '王五');

查看 teacher 表中的數據

select * from teacher;

創建學生成績表stu_sco

create table stu_sco(s_id varchar(10),c_id varchar(10),score decimal(18,1)) engine=InnoDB default charset utf8;
insert into stu_sco values ('01' , '01' , 80), ('01' , '02' , 90), ('01' , '03' , 99), ('02' , '01' , 70), ('02' , '02' , 60), ('02' , '03' , 80), ('03' , '01' , 80), ('03' , '02' , 80), ('03' , '03' , 80), ('04' , '01' , 50), ('04' , '02' , 30), ('04' , '03' , 20), ('05' , '01' , 76), ('05' , '02' , 87), ('06' , '01' , 31), ('06' , '03' , 34), ('07' , '02' , 89), ('07' , '03' , 98);

查看 stu_sco 表中的數據

select * from stu_sco;

效果圖

 

 

 

接下來就是對sql的操作;

完成如下查詢語句

1、查詢"01"課程比"02"課程成績高的學生信息及課程分數

SELECT a.*, b.score AS sc1, c.score AS sc2
FROM student a
JOIN stu_sco b
ON a.s_id = b.s_id
AND b.c_id = 1
JOIN stu_sco c
ON a.s_id = c.s_id
AND c.c_id = 2
WHERE b.score > c.score;

sql解析:給student表起個別名 a ,給stu_sco表起個別名b,給stu_sco表起個別名c 。注意:b表和c表本質上是同一張表,名字不同而已。然后把這三張表用JOIN連接起來,很顯然我們要的不是三張表的全部數據,所以我們要在ON后面加上我們想要過濾的條件。Where后面在加上限制條件,就能得到我們想要的數據。

MySQL中 join的用法:join具有 連接的作用,即當兩個或者兩個以上的表有關系時,需要用join來連接這些相關的表,來處理或分析數據。

舉個例子,我用teacher表course表進行連接

執行select * from teacher JOIN course;之后,等到得新表為

            

 

 

 

 course表和teacher表一一匹配,得出一個新表

新表的列名是兩個表列名加起來的,可能會產生相同的列名,如t_id
先用表course中的一行數據和表teacher中的每一行數據不斷的拼接,產生新的行
再用表course的第二行去和表teacher中的每一行數據拼接,以此類推
表chourse是3行,表teacher是2=3行,所以按照上面的規律會產成3*3 = 9行的新的表

 

 

 一般我們join后的表,並不是我們想要的,這時,可以用 ON 來加一些條件:

例如:teacher join course on teacher.t_id = course.t_id ,on后面就是我們加的條件,我們想要teacher.t_id這一列數據和course.t_id這一列的數據相等的數據,這里注意一下,join后的表列名是有重復的,所以ON后面的條件語句中我們要加上原來的表名。

select * from teacher join course on teacher.t_id = course.t_id;

 

2、查詢平均成績大於等於60分的同學的學生編號和學生姓名和平均成績

SELECT student.s_id AS 學生編號, student.s_name AS 學生姓名, AVG(score) AS 平均成績
FROM student
    JOIN stu_sco ON student.s_id = stu_sco.s_id
GROUP BY student.s_id, student.s_name
HAVING 平均成績 >= 60;

 

 

 

sql解析:從student表和stu_sco表中查詢出學生編號,學生姓名,學生平均成績,並且學生平均成績要大於60

 

 

 MySQL中 GROUP BY的用法:

1、當聚集函數和非聚集函數出現在一起時,需要將非聚集函數進行group by
2、當只做聚集函數查詢時候,就不需要進行分組了。

MySQL中的聚合函數用來對已有數據進行匯總,如求和、平均值、最大值、最小值等。

count(col): 表示求指定列的總行數
max(col): 表示求指定列的最大值
min(col): 表示求指定列的最小值
sum(col): 表示求指定列的和
avg(col): 表示求指定列的平均值


簡單的說,就是先看select 后面的字段,看他要查詢那些字段。

其中數據表中有的字段叫非聚集函數,比如上面的student.s_name和student.s_id;這兩個字段是student表中有的字段

 

 

 而數據表中沒有的字段叫聚集函數,比如平均成績是通過聚合函數AVG(score)出來的

比如張三的各科成績的score為語文:100,數學:98

AVG(score)之后就是99,要區別開:score是非聚集函數,但是AVG(score)是聚集函數。

對於上面的sql,我們就要用

GROUP BY student.s_id, student.s_name

對這兩個非聚集函數分組,如果不用GROUP BY分組,就會出現下面的錯誤

 

 

 

 MySQL中 HAVING的用法:

having一般和group by 配合使用。

誤區:不要錯誤的認為having和group by 必須配合使用。

例如:沒有group by也能用having

 

 

 

對於非聚集函數,having和where的用法是一樣的

 

 

 但是,如果select后面沒有那個字段,但是數據表中有那個字段,此時只能用where(大家可以仔細看看兩張截圖中sql語句的區別)

 

 

 

對於聚集函數,只能用having

3、查詢所有同學的學生編號、學生姓名、選課總數、所有課程的總成績

SELECT student.s_id AS 學生編號, student.s_name AS 學生姓名, COUNT(c_id) AS 選課總數
    , SUM(score) AS 總成績
FROM student
    JOIN stu_sco ON student.s_id = stu_sco.s_id
GROUP BY student.s_id, student.s_name;

4、查詢"李"姓老師的數量

SELECT COUNT(*) AS 李姓老師的數量
FROM teacher
WHERE t_name LIKE '李%';

MySQL LIKE 語法:

LIKE運算符用於WHERE表達式中,以搜索匹配字段中的指定內容,語法如下:

WHERE column LIKE 參數

WHERE column NOT LIKE 參數

在LIKE全面加上NOT運算符時,表示與LIKE相反的意思,即選擇不包含參數的數據記錄

LIKE通常與通配符%一起使用,而不加通配符%的LIKE語法,表示精確匹配,其實際效果等同於 = 等於運算符

 MySQL中 %的用法:

%在sql語句中表示通配符,在模糊查詢中用到 如查詢姓名以 李開頭的 就寫成 like ‘李%’ 如 姓名以 李結尾的 寫成 like ‘%李’。 姓名中包含 李的 寫成 like '%李%'

5、查詢學過"張三"老師授課的同學的信息

SELECT *
FROM student
WHERE s_id IN (
    SELECT s_id
    FROM stu_sco
    WHERE c_id IN (
        SELECT c_id
        FROM course
        WHERE t_id IN (
            SELECT t_id
            FROM teacher
            WHERE t_name = '張三'
        )
    )
);

sql解析:查詢student表中s_id的范圍在 ( 查詢stu_sco表中c_id的范圍在 ( 查詢teacher表中的t_id限制條件是t_name=’張三' ) )中的數據

 

 

詳細信息如下

 

 

MySQL中 IN 的用法:

in常用於where表達式中,其作用是查詢某個范圍內的數據。

例如:查詢student表中,s_id的值的范圍是01,02,03的數據

PS: not in與in作用相反

例如:查詢student表中,s_id的值的范圍不是01,02,03的數據

6、查詢學過編號為"01"並且也學過編號為"02"的課程的同學的信息

SELECT *
FROM student
WHERE s_id IN (
    SELECT a.s_id
    FROM (
        SELECT *
        FROM stu_sco
        WHERE c_id = '01'
    ) a
        JOIN (
            SELECT *
            FROM stu_sco
            WHERE c_id = '02'
        ) b
        ON a.s_id = b.s_id
);

sql解析:查詢學生表中的全部信息,限制條件是s_id在(查詢stu_sco表中s_id為兩個stu_sco表的數據,其中a的c_id為01,b的c_id為02並且兩個表中的s_id要相等)范圍內的數據

7、查詢學過編號為"01"但是沒有學過編號為"02"的課程的同學的信息

SELECT student.*
FROM student, stu_sco sc1
WHERE student.s_id = sc1.s_id
    AND sc1.c_id = '01'
    AND student.s_id NOT IN (
        SELECT s_id
        FROM stu_sco sc2
        WHERE sc2.c_id = '02'
    );

 sql解析:根據student表和stu_sco表來查詢student表中的所有數據,限制條件是student表中的s_id和stu_sco表中的s_id相等,並且stu_sco表中的c_id等於01,和學生表中的s_id不在(根據stu_sco表查詢s_id,限制條件是c_id不等於02)范圍內。

8、查詢沒有學全所有課程的學生信息

SELECT student.*
FROM student
    JOIN stu_sco ON student.s_id = stu_sco.s_id
GROUP BY student.s_id, student.s_name, student.s_age, student.s_sex
HAVING COUNT(stu_sco.c_id) < (
    SELECT COUNT(DISTINCT c_id)
    FROM course
);

 

 sql解析:從student表中查詢student的全部信息,把student表和stu_sco表做關聯,關聯條件是student.s_id = stu_sco.id,把字段進行分組,限制條件是stu_sco.c_id的數據量小於從course表中查詢出來的c_id的數量。

MySQL中 DISTINCT 的用法:

DISTINCT 關鍵字是去重的,如果查詢的是單個字段的就是去掉單個字段中重復的數據,如果查詢的是多個字段,那么去重的是多個字段中完全相同的數據。

9、查詢至少有一門課與學號為"01"的同學所學相同的同學的信息

SELECT student.*
FROM student
WHERE s_id IN (
    SELECT DISTINCT s_id
    FROM stu_sco
    WHERE c_id IN (
            SELECT c_id
            FROM stu_sco
            WHERE s_id = '01'
        )
        AND s_id <> '01'
);

 

 sql解析:從學生表查詢學生信息,限制條件是s_id在(從stu_sco中查詢s_id,並且s_不等於 '01' ,限制條件是c_id在(從stu_sco表中查詢c_id,限制條件是s_id = '01')范圍內)范圍內

MySQL中 <> 的用法:

!=,<> 兩者都是不等於的意思,!= 是以前sql標准,<> 是現在使用的sql標准,推薦使用 <>。

10、查詢和"01"號的同學學習的課程完全相同的其他同學的信息

SELECT student.*
FROM student
WHERE s_id IN (
    SELECT s_id
    FROM stu_sco
    WHERE s_id <> '01'
    GROUP BY s_id
    HAVING COUNT(1) = (
        SELECT COUNT(c_id)
        FROM stu_sco
        WHERE s_id = '01'
    )
);

 

 sql解析:從student表中查詢student全部信息,限制條件是s_id在(從stu_sco表中查詢s_id,限制條件是s_id不等於 '01' 並且用s_id做分組,統計s_id中每個s_id的數量等於從stu_sco表中查詢c_id的數量,限制條件是s_id等於 '01')范圍內

 

(未完,待補充)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM