序文
今日、私はmysqlトレーニングの質問を読みました。そのうちの1つは非常に興味深いものです。
SQLソリューションも以下に記述されています。group_concat()関数を使用して、グループ化後にフィールドのグループ(名前など)をデフォルトでコンマで区切ってつなぎ合わせます。この考えは問題ありませんが、スコアテーブルに情報を挿入する順序が間違っているので、どのように確認しますか?
それから私は他の何人かの人々の答えを読みました、そして何人かは比較のためにコースの数を使用しました、そして書き込みは非常に乱雑でした。しばらく考えてみたら、存在しないものを使って答えることは可能だと思います。
存在する存在しない存在する
原理説明:
存在します(sqlは真の結果セットを返します)
存在しません(sqlは結果セットをtrueとして返さないか、結果セットをfalseとして返します)
これはかなり厄介に見えます。ここでは、存在するものと存在しないものの原則と使用法について詳しく説明します。
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);
まず、existsを使用したSQLステートメントの実行順序を知る必要があります。最初に外部クエリが実行され、次に内部クエリが実行されることに注意してください。これは、私たちが学んだサブクエリの概念と「矛盾」します。特に、サブクエリを学習した直後に学習が存在した後は、単なるクラッシュです。
詳細な手順(使用が存在します):
1.最初にAから外部クエリselect *を実行し、次に外部クエリからデータを取得して内部クエリに渡します。
2.内部クエリはselect * from Bを実行し、外部クエリによって渡されたデータと内部クエリによって取得されたデータは、背後の条件に従って照合されます。A.id= B.idを満たすデータがある場合、いずれも満たされない場合はtrueを返します。 falseを返します。
3.内部クエリがtrueを返した場合、外部クエリのデータは保持されます。それ以外の場合、内部クエリがfalseを返した場合、外部クエリのデータは表示されません。外側のクエリのすべてのデータは、行ごとに照合されます。
「存在しない」と「存在する」の使い方は逆なので、言葉遣いを続けることはありません。
ケーススタディ
または、上記の質問に従って分析し、存在しないか存在するかを確認します。
# 学生表
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));