MySQL学习(1)—— 数据查询(SELECT)

SQL的功能:(1)数据查询:SELECT

                      (2)数据定义:CREATE、DROP、ALTER

                      (3)数据更新:INSERT 、UPDATE、DELETE

                      (4)数据控制:GRANT、REVOKE

对下面该表进行查询:

MySQL学习(1)—— 数据查询(SELECT)_第1张图片

SELECT语句的一般格式如下(中括号里的语句是可选的):

SELECT  [ALL|DISTINCT]  <目标列表达式> [,<目标列表达式>] ......

FROM  <表名> [,<表名>]

[WHERE <条件表达式>]

[GROUP BY <列名 1> [HAVING <条件表达式>]  ]

[ORDER BY <列名 2> [ASC | DESC] ];

①根据WHERE的条件表达式,从FROM指定的表中找出满足条件的元组,再按SELECT中的目标列表达式选出元组中的指定属性来形成结果表。

②GROUP BY语句将结果按<列名 1>的值进行分组,该属性列值相等的元组分为一个组。如果带有HAVING语句,则只有满足条件表达式的组才予以输出。

③ORDER BY将结果按照<列名 2>的值的升序(ASC)或降序(DESC)进行排序。

一. 基本查询(SELECT ...  FROM ...)

        1. 查询指定列

#查询全体学生的学号和姓名
SELECT Sno,Sname
FROM student;

#查询全体学生的详细记录
SELECT *
FROM student;

        2. 指定别名

#指定别名
SELECT Sname AS "Name", Sage AS "Age"
FROM student;
#查询全体学生的姓名、出生年份 
SELECT Sname AS "Name",2021-Sage AS "Birthday"
FROM Student;
#条件表达式为常数 
SELECT '学生',Sno,Sname
FROM Student; 

        3. 消除重复的行(DISTINCT)

#查询选修了课程的学生学号
SELECT DISTINCT Sno     #如果不使用DISTINCT,则默认是ALL
FROM SC;

       4. 显示表中各属性的详细信息

DESCRIBE Student;

二. WHERE

查询条件 谓词
比较 =,>,<,>=,<=,!=
确定范围 BETWEEN AND,NOT BETWEEN AND
确定集合 IN,NOT IN
字符匹配 LIKE,NOT LIKE
空值 IS NULL,IS NOT NULL
逻辑运算 AND,OR,NOT

1. 比较大小

#查询计算机科学与技术专业的学生名单
SELECT Sname
FROM student
WHERE Sdept = '计算机科学与技术';
#查询所有年龄在21岁以下的学生姓名和年龄
SELECT Sname,Sage
FROM student
WHERE Sage<21;

2. 确定范围

#查询年龄在20-23岁(包括20和23)之间的学生姓名、年龄、性别
SELECT Sname,Sage,Ssex
FROM student
WHERE Sage BETWEEN 20 AND 23;
#查询年龄不在20-23岁之间的学生姓名、年龄、性别
SELECT Sname,Sage,Ssex
FROM student
WHERE Sage NOT BETWEEN 20 AND 23;

3. 确定集合

#查询计算机科学与技术、软件工程专业的学生姓名、性别
SELECT Sname,Ssex
FROM student
WHERE Sdept IN ('计算机科学与技术','软件工程');

4.字符匹配

   LIKE '<匹配串>' [ESCAPE '<换码字符>']

   查找指定的属性列值与<匹配串>相匹配的元组,<匹配串>可以是一个完整的字符串,也可以含有通配符%(代表任意长度)和 _(代表一个字符);如果要查询的字符串本身含有通配符%或_,这时需要使用ESCAPE '<换码字符>' 对通配符进行转义。

#查询所有姓张的学生姓名、学号、性别
SELECT Sname,Sno,Ssex
FROM student
WHERE Sname LIKE '张%';
#查询姓名第二个字为“三”的学生的姓名、性别
SELECT Sname,Ssex
FROM student
WHERE Sname LIKE '_三';
#查询课程名为'DB_Design'的课程号和学分
SELECT Cno,Ccredit
FROM course
WHERE Cname LIKE 'DB/_Design' ESCAPE '/';    #ESCAPE '/'表示/为换码字符,这样/后的字符'_'不再具有通配符的含义
#查询课程名以'DB_'开头,且倒数第三个字符为i的课程的详细情况
SELECT *
FROM course
WHERE Cname LIKE 'DB/_%i__' ESCAPE '/';

5. 空值

#查询有成绩的学生学号、课程号
SELECT Sno,Cno
FROM SC
WHERE Grade IS NOT NULL;

6. 逻辑运算

#查询软件工程专业男生的姓名和学号
SELECT Sname,Sno
FROM student
WHERE Sdept = '软件工程' AND Ssex = '男';

三. ORDER BY

#查询选修了课程号为2的学生学号和成绩,查询结果按照分数的降序排列
SELECT Sno,Grade
FROM SC
WHERE Cno = 2
ORDER BY Grade DESC;
#查询所有学生的姓名、性别、专业,结果按照年龄降序、学号升序排列 
SELECT Sname,Ssex
FROM Student
ORDER BY Sage DESC, Sno ASC;

四. 分页显示(LIMIT)

#查询所有学生的学号、姓名、年龄,每页显示两条数据,此时显示第一页
SELECT Sno,Sname,Sage
FROM Student
LIMIT 0,2;         #LIMIT 偏移量,每页显示的数量

#查询所有学生的学号、姓名、年龄,每页显示两条数据,此时显示第2页
SELECT Sno,Sname,Sage
FROM Student
LIMIT 2,2;

五. 聚集函数

COUNT(*) 统计元组的个数
COUNT( [DISTINCT | ALL ] <列名> ) 统计一列中值的个数
SUM( [DISTINCT | ALL ] <列名> ) 计算一列值的总和
AVG( [DISTINCT | ALL ] <列名> ) 计算一列值的平均值
MAX( [DISTINCT | ALL ] <列名> ) 求一列值中的最大值
MIN( [DISTINCT | ALL ] <列名> ) 求一列值中的最小值
#查询学生的总人数 
SELECT COUNT(*)
FROM Student;
#查询选修了课程的学生人数
SELECT COUNT(DISTINCT Sno)
FROM SC;
#查询选修了1号课程的学生的平均成绩
SELECT AVG(Grade)
FROM SC
WHERE Cno = 1;
#查询选修了1号课程的学生的最高分数
SELECT MAX(Grade)
FROM SC
WHERE Cno = 1;
#查询学号为121301的学生选修课的总分数
SELECT SUM(Grade)
FROM SC
WHERE Sno = 121301;

六. GROUP BY

#求各个课程号及相应的选课人数
SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;
#查询选修了2门以上课程的学生学号
SELECT Sno
FROM SC
GROUP BY Sno HAVING COUNT(*)>2;
#查询平均成绩大于等于90分的学生学号和成绩
SELECT Sno,Grade
FROM SC
GROUP BY Sno HAVING AVG(Grade) >= 90;

七. 多表查询

1.等值连接

#查询所有学生及其选课情况 
SELECT Student.Sno,Sname,Sage,Ssex,Sdept,Cno,Grade
FROM Student,SC
WHERE Student.Sno = SC.Sno;
#查询选修了1号课程且成绩在90分以上的所有学生的学号、姓名和性别
SELECT Student.Sno,Sname,Ssex
FROM Student,SC
WHERE Student.Sno = SC.Sno AND SC.Cno = 1 AND SC.Grade > 90;
#查询每个学生的学号、姓名、选修的课程名及成绩
SELECT Student.Sno,Sname,Course.Cname,Grade
FROM Student,Course,SC
WHERE Student.Sno = SC.Sno AND SC.Cno = Course.Cno;

2.内连接

#查询所有学生及其选课情况 
SELECT Student.Sno,Sname,Sage,Ssex,Sdept,Cno,Grade
FROM Student JOIN SC
ON Student.Sno = SC.Sno;

3.外连接

由于Student表中不是每个学生都有选修课,因此SC中没有全部的学生,因此在内连接时,没有选课的学生无法显示。如果仍想把Student中没有选课的学生元组保存在结果表中,而在SC表的属性上填空值NULL,这时需要进行外连接。左外连接列出左边关系(如Student)中所有的元组,右外连接列出右边关系(如SC)中所有的元组。

SELECT Student.Sno,Sname,Sage,SSex,Sdept,Cno,Grade
FROM Student LEFT OUTER JOIN SC 
ON Student.Sno = SC.Sno;

4.自身连接

#查询每一门课的先行课 
SELECT FIRST.Cno,SECOND.Cpno
FROM Course AS FIRST,Course AS SECOND
WHERE FIRST.Cpno = SECOND.Cno;

八. 嵌套查询 

1. 单行子查询(子查询返回单值) 

    单行子查询使用比较运算符

#查询与“张三”在同一个专业学习的学生学号、姓名 
SELECT Sno,Sname
FROM Student
WHERE Sdept =  (SELECT Sdept
				FROM Student
				WHERE Sname = '张三');
#找出每个学生超过他自己选修课平均成绩的学号、课程号 
SELECT Sno,Cno
FROM SC AS x
WHERE Grade >= (SELECT AVG(Grade)
				FROM SC AS y
				WHERE y.Sno = x.Sno);   #依次将x的Sno赋值给y的Sno,求出其均值

2.多行子查询(子查询返回多值)

    多行子查询使用IN、ANY(SOME)、ALL谓词修饰符

  (1)IN:等于列表中的任意一个

#查找选课大于等于2门的学生姓名
SELECT Sname
FROM Student
WHERE Student.Sno IN (SELECT SC.Sno
					  FROM SC
                      GROUP BY SC.Sno HAVING COUNT(*) >= 2);

  (2)ANY(SOME):需要和比较运算符一起使用,用于和子查询的某一个值比较

#查询非软件工程专业中比软件工程专业中任意一个学生年龄小的学生姓名和年龄 
SELECT Sname,Sage
FROM Student
WHERE Sage 

  (3)ALL:需要和比较运算符一起使用,用于和子查询的所有值比较

#查询非软件工程专业中比软件工程专业中所有学生年龄都小的学生姓名和年龄
SELECT Sname,Sage
FROM Student
WHERE Sage 

3.带有谓词EXISTS的子查询

   带有谓词EXISTS的子查询不返回任何数据,只产生逻辑真或逻辑假

#查询所有选修了1号课程的学生姓名 
SELECT Sname
FROM Student
WHERE EXISTS (SELECT *
			  FROM SC
              WHERE Sno = Student.Sno AND Cno = 1);
#查询选修了全部课程的学生姓名 
SELECT Sname
FROM Student
WHERE NOT EXISTS (SELECT * 
				  FROM Course
                  WHERE NOT EXISTS (SELECT *
									FROM SC
                                    WHERE Sno = Student.Sno AND Cno = Course.Cno));

你可能感兴趣的:(MySQL,mysql)