前言
今天看了下mysql訓練題,其中有一題很有意思,

? 下面也寫了sql解答,使用了group_concat()函式,這個函式是分組后將一組的欄位(比如name)拼接在一起,默認以逗號分隔,這個思路可以,但是在成績表插入資訊時的順序是亂的,那又怎么查,
我然后看了幾個其他人的答案,還有的用課程數作比較的,寫的很亂很雜,想了一會,覺得使用not exists解答是可以的,
exists與not exists
原理解釋:
exists(sql回傳結果集為真)
not exists(sql不回傳結果集為真或回傳結果集為假)
這看的挺懵逼的,這里詳細的解釋下exists和not exists的原理和用法吧,
select * from A where not exists(select * from B where A.id = B.id);
select * from A where exists(select * from B where A.id = B.id);
首先我們要知道sql陳述句使用了exists或not exists后的執行順序,注意,是先執行外查詢再執行內查詢,這和我們學的子查詢概念就“沖突了”,特別是剛學完子查詢后再學exists,簡直讓人崩潰,
詳細步驟(使用exists):
1,首先執行外查詢select * from A,然后從外查詢的資料取出一條資料傳給內查詢,
2,內查詢執行select * from B,外查詢傳入的資料和內查詢獲得資料根據where后面的條件做匹對,如果存在資料滿足A.id=B.id則回傳true,如果一條都不滿足則回傳false,
3,內查詢回傳true,則外查詢的這行資料保留,反之內查詢回傳false則外查詢的這行資料不顯示,外查詢的所有資料逐行查詢匹對,
not exists和exists的用法相反,就不繼續啰嗦了,
案例分析
還是根據上面的那道題做分析來看看not exists或exists是如何用的吧,
# 學生表
CREATE TABLE `Student`(
`s_id` VARCHAR(20),
`s_name` VARCHAR(20) NOT NULL DEFAULT '',
`s_birth` VARCHAR(20) NOT NULL DEFAULT '',
`s_sex` VARCHAR(10) NOT NULL DEFAULT '',
PRIMARY KEY(`s_id`)
);
# 課程表
CREATE TABLE `Course`(
`c_id` VARCHAR(20),
`c_name` VARCHAR(20) NOT NULL DEFAULT '',
`t_id` VARCHAR(20) NOT NULL,
PRIMARY KEY(`c_id`)
);
# 教師表
CREATE TABLE `Teacher`(
`t_id` VARCHAR(20),
`t_name` VARCHAR(20) NOT NULL DEFAULT '',
PRIMARY KEY(`t_id`)
);
# 成績表
CREATE TABLE `Score`(
`s_id` VARCHAR(20),
`c_id` VARCHAR(20),
`s_score` INT(3),
PRIMARY KEY(`s_id`,`c_id`)
);
# 插入學生表測驗資料
insert into Student values('01' , '趙雷' , '1990-01-01' , '男');
insert into Student values('02' , '錢電' , '1990-12-21' , '男');
insert into Student values('03' , '孫風' , '1990-05-20' , '男');
insert into Student values('04' , '李云' , '1990-08-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吳蘭' , '1992-03-01' , '女');
insert into Student values('07' , '鄭竹' , '1989-07-01' , '女');
insert into Student values('08' , '王菊' , '1990-01-20' , '女');
#課程表測驗資料
insert into Course values('01' , '語文' , '02');
insert into Course values('02' , '數學' , '01');
insert into Course values('03' , '英語' , '03');
# 教師表測驗資料
insert into Teacher values('01' , '張三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');
#成績表測驗資料
insert into Score values('01' , '01' , 80);
insert into Score values('01' , '02' , 90);
insert into Score values('01' , '03' , 99);
insert into Score values('02' , '01' , 70);
insert into Score values('02' , '02' , 60);
insert into Score values('02' , '03' , 80);
insert into Score values('03' , '01' , 80);
insert into Score values('03' , '02' , 80);
insert into Score values('03' , '03' , 80);
insert into Score values('04' , '01' , 50);
insert into Score values('04' , '02' , 30);
insert into Score values('04' , '03' , 20);
insert into Score values('05' , '01' , 76);
insert into Score values('05' , '02' , 87);
insert into Score values('06' , '01' , 31);
insert into Score values('06' , '03' , 34);
insert into Score values('07' , '02' , 89);
insert into Score values('07' , '03' , 98);
題目是查詢和"01"號的同學學習的課程完全相同的其他同學的資訊,直接做確實有點麻煩,我們可以先做做這題:查看學了所有課程的同學的資訊,
學了所有課程的同學的資訊,那不就是這些同學沒有一門課程沒有學嗎,
select * from Student st where not exists(select * from Course c
where not exists(select * from Score sc where sc.c_id = c.c_id
and sc.s_id = st.s_id));

然后我們再回過來看這題,是不是和剛才的題一模一樣,只不過把所有的課程換成01同學學的課程,
select * from Student st where not exists(select * from
( select s2.c_id as c_id from Student s1
inner join Score s2 on s1.s_id = s2.s_id where s1.s_id = 01) t
where not exists (select * from Score sc
where sc.c_id = t.c_id and sc.s_id = st.s_id and st.s_id != 01));

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/197017.html
標籤:java
