数据库补充(SQL语句:DML&&DQL)

目录

1.1 多表关联查询

1.1.1 外连接查询

1.1.2 自然连接查询

1.2 子查询

1.3 SQL函数

1.3.1 聚合函数

补充:COUNT(*) 和 COUNT(1) 和 COUNT(字段名)  三者区别

COUNT(*) 和 COUNT(1)

COUNT(1) 和 COUNT(字段)

三者区别:

1.3.2 数值型函数

1.3.3 字符串函数

1.3.4 日期函数

1.3.5 流程控制函数


1.1 多表关联查询

1.1.1 外连接查询

左外连接

LEFT JOIN        获取相交数据+左外关键字以左表的全部数据

右外连接

RIGHT JOIN        获取相交数据+右外关键字以右的全部数据

示例:

#左外连接
SELECT s.StudentName "姓名",s.Address "住址",g.GradeName "班级名称"
FROM grade g LEFT JOIN student s ON s.GradeID = g.GradeID;

#右外连接
SELECT s.StudentName "姓名",s.Address "住址",g.GradeName "班级名称"
FROM student s RIGHT JOIN grade g ON s.GradeID = g.GradeID;

1.1.2 自然连接查询

        自己和自己形成主外键关系

+------------+-----+-----------------+
| categoryId | pid | categoryName    |
+------------+-----+-----------------+
|          2 |   1 | 美术设计        |
|          3 |   1 | 软件开发        |
|          4 |   3 | 数据库基础      |
|          5 |   2 | Photoshop基础   |
|          6 |   2 | 色彩搭配学      |
|          7 |   3 | PHP基础         |
|          8 |   3 | 一起学JAVA      |
+------------+-----+-----------------+

假设:

        1 意味着是根目录

        编号 2 的美术设计 和 编号 3 的软件开发  父级都是 1  根目录

        编号为 3 的数据库基础 是软件开发的一部分

SELECT c1.categoryName "父级目录",c2.categoryName "子栏目"
FROM category c1 INNER JOIN category c2 ON c1.categoryId = c2.pid;

1.2 子查询

将一个查询语句的结果充当下一个查询语句的条件
核心在于通过小括号以提高优先级别
子查询中可以包含的关键字        IN   NOT   ALL
子查询中可以包含的运算符        逻辑  +  算数

示例:

#查询大一的男生姓名以及家庭住址

#大一对应的班级编号 --- 1
SELECT GradeID FROM grade WHERE GradeName = '大一';
#以一年级一班对应的班级编号作为线索,去查找适配的学生信息
SELECT StudentName "姓名",Address "住址"
FROM student WHERE GradeID = (SELECT GradeID FROM grade WHERE GradeName = '大一');
#加入基础条件
SELECT StudentName "姓名",Address "住址"
FROM student WHERE GradeID = (SELECT GradeID FROM grade WHERE GradeName = '大一') AND sex = 1;
#查询班级名称是大一(学生信息 ==> 学号信息),科目是高等数学-1(科目编号)的学生的平均分

#根据班级名 找出班级 编号
SELECT GradeID
FROM grade WHERE GradeName = '大一';
#根据对应的班级编号 找到适配的学生学号
SELECT StudentNo
FROM student WHERE GradeID = (SELECT GradeID
FROM grade WHERE GradeName = '大一')
#根据科目名找到对应的科目编号
SELECT subjectNo
FROM subject WHERE subjectName = '高等数学-1';
#编辑最后的命令
SELECT AVG(result.StudentResult)
FROM result
WHERE result.SubjectNo = (SELECT subjectNo
FROM subject WHERE subjectName = '高等数学-1')
AND result.StudentNo IN (SELECT StudentNo
FROM student WHERE GradeID = (SELECT GradeID
FROM grade WHERE GradeName = '大一'));

1.3 SQL函数

1.3.1 聚合函数

        聚合函数是指对一组值进行运算,最终返回的是单个值

        也可以称为        组合函数

COUNT() 统计目标行数量的函数
AVG() 求平均值
SUM() 求和
MIN() 求最小值
MAX() 求最大值

注意:

        除COUNT 函数之外,其他的聚合函数都会忽略 NULL 值

补充:COUNT(*) 和 COUNT(1) 和 COUNT(字段名)  三者区别

COUNT(*) 和 COUNT(1)

        当表 数据量较大 的时候,对表进行检索,COUNT(1)  时效要比  COUNT(*)   慢

        当表 数据量较小 的时候,对表进行检索,COUNT(1)  时效要比  COUNT(*)   快

        COUNT(1)        聚索引状

        COUNT(*)        自动选择索引

结论:

        这两个 通常 不予比较

COUNT(1) 和 COUNT(字段)

        COUNT(1)  会统计表中所有的记录数,包含了字段为 NULL 的记录

        COUNT(字段)  会忽略当前字段中出现 NULL 的情况,如果出现 NULL 值,不统计这条记录

三者区别:

列名<===>主键列 COUNT(字段) > COUNT(*) > COUNT(1)
列名!<===>主键列 COUNT(*) || COUNT(1) > COUNT(字段)
表多列都无主键 COUNT(1) > COUNT(*) > COUNT(字段)

执行效率最高的

        SELECT COUNT(主键列)......

1.3.2 数值型函数

函数名称 作用
ABS() 求绝对值
SQRT() 求平方根
POW() 或 POWER() 返回参数的幂次方
MOD() 求余数
CEIL() 或 CEILING() 向上取整
FLOOR()

向下取整

ROUND() 四舍五入
RAND 随机生成一个数字(0~1)之间

示例:

#随机生成 0~99999 的数字

#随机生成一个数字    (0~1)    之间
SELECT RAND();
#将生成的随机数 *100000
SELECT RAND()*100000;
#对结果进行 FLOOR 向下取整
SELECT FLOOR(RAND()*100000);

1.3.3 字符串函数

函数名称 作用
LENGTH() 返回字符串长度
CHAR_LENGTH() 返回字符串的字节长度
CONCAT() 合并字符串长度,返回结果为连续后新生成的字符串,参数可以是一个或者多个
INSERT(str,pos,len,new,str) 替换字符串函数
LOWER()

将字符串内所有的字符转小写

UPPER()

将字符串中所有的字符转大写

LEFT(str,len) 从字符串左侧进行截取,返回字符串左边若干长度的字符
RIGHT(str,len) 从字符串右侧进行截取,返回字符串右边若干长度的字符
TRIM() 删除字符串两次空格
REPLACE(str,l1,l2) 字符串替换函数,返回替换后的新字符串
SUBSTRING(str,s,len) 截取字符串,返回从指定位置开始指定长度的字符串
REVERSE() 字符串逆序函数,返回余元字符串顺序相反的字符串
STRCMP(str1,str2) 比较两个表达式的顺序,如果str1小于str2返回 -1 0相等 1大于
LOCATE(substr,str) 返回第一次出现目标字符串的索引位
INSTR(substr,str) 返回最后一次出现目标字符串的索引位

1.3.4 日期函数

函数名称 作用

CURDATE()

CURRENT_DATE()

CURRENT_DATE

返回当前系统的日期值

CURTIME()

CURRENT_TIME() CURRENT_TIME

返回当前系统的时间

NOW()

SYSDATE()

返回当前系统的日期及时间
DATE(PAREM) 返回指定对象的日期部分
TIME(PAREM) 返回指定对象的时间部分
YEAR(PAREM) 返回指定对象的年份(1970--2069)
MONTH(PAREM) 返回指定对象的月份
DAY(PAREM) 返回指定对象的日期
DAYOFWEEK(PAREM) 获取指定日期对应的一周的索引位置值,也就是星期数,注意周日是开始日,为1
WEEK(PAREM) 获取指定日期是一年中的第几周,返回值的范围是否为 0〜52
DATEDIFF(PAREM,PAREM) 返回两个日期之间的相差天数

示例:

#查询A学生和当前时间的天数差
SELECT DATEDIFF(NOW(),(SELECT BornDate FROM student WHERE StudentName = '张三'));

#根据生日查询其年龄
SELECT FLOOR(DATEDIFF(NOW(),(SELECT BornDate FROM student WHERE StudentName = '张三'))/365) AS "时差";

1.3.5 流程控制函数

函数名称 作用
IF(条件,结果1,结果2) 判断,如果条件=true 返回结果1 反之 返回结果2
CASE 搜索函数
IFNULL(value1,value2) 判断,如果value1不为NULL 则函数返回值就是value1 反之 返回value2

示例:

SELECT IF(12,2,3);
SELECT IF(1<2,'YES','NO');
SELECT IF(STRCMP('TEST001','TEST001'),'NO','YES');
条件内  结果 true(非0的自然数)    false(0)

#分别显示学生信息,有邮箱和没有邮箱的备注信息
SELECT StudentName "学生姓名",IF(Email IS NULL,'没有邮箱','存在邮箱') "是否具有邮箱"
FROM student;

#使用IFNULL,函数入参两个,如果入参不为空则返回第一个值,否则返回第二个值
SELECT IFNULL(1,2),IFNULL(NULL,2),IFNULL(9/3,2);

SELECT StudentName "学生姓名",IFNULL(Email,'没有邮箱') "邮箱地址"
FROM student;
#示例
CASE<表达式>
	WHEN<值1>  THEN<结果1>
	WHEN<值2>  THEN<结果2>
	WHEN<值3>  THEN<结果3>
	WHEN<值4>  THEN<结果4>
ELSE <默认结果>
END
#需求 查询成绩表  限定考试科目 高等数学-1 
#	 要求如下   如果学号是1000   显示成绩为原成绩的 1.5倍
#	 要求如下   如果学号是1001   显示成绩为原成绩的 1.3倍
#	 要求如下   如果学号是1002   显示成绩为原成绩的 1.1倍
#	 要求如下   其他学生成绩显示原成绩

#1---查出高数-1的科目编号
SELECT SubjectNo FROM subject WHERE SubjectName = '高等数学-1';
#2---通过科目编号找到学生的考试成绩
SELECT * FROM result WHERE SubjectNo = (SELECT SubjectNo FROM subject WHERE SubjectName = '高等数学-1');
#3---通过CASE语法修改并查看参数
SELECT StudentNo "学号",StudentResult "原成绩",
CASE StudentNo
	WHEN 1000 THEN StudentResult*1.5
	WHEN 1001 THEN StudentResult*1.3
	WHEN 1002 THEN StudentResult*1.1
	ELSE StudentResult
	END "修改后的成绩"
FROM result 
WHERE SubjectNo = (SELECT SubjectNo FROM subject WHERE SubjectName = '高等数学-1');

你可能感兴趣的:(数据库,sql)