数据库SQL语言以及DQL的学习

Posted 黑黑白白君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库SQL语言以及DQL的学习相关的知识,希望对你有一定的参考价值。



相关的背景知识

本栏的《【数据库(一)】数据库基础知识及MySQL常用命令》(https://blog.csdn.net/m0_37621024/article/details/116547612)


1)SQL语言

1.1 什么是SQL语言?

结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统

通过SQL,可以访问和处理数据库,包括数据插入、查询、更新和删除。

  • 结构化查询语言是高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同数据库系统
  • 可以使用相同的结构化查询语言作为数据输入与管理的接口。结构化查询语言语句可以嵌套,这使它具有极大的灵活性和强大的功能。


    SQL 在1986年成为 ANSI(American National Standards Institute 美国国家标准化组织)的一项标准,在 1987 年成为国际标准化组织(ISO)标准。

1.2 为什么需要SQL语言?

按照ANSI(美国国家标准协会)的规定,SQL成为关系型数据库管理系统的标准语言。SQL语句可以用来执行各种各样的操作,例如更新数据库中的数据,从数据库中提取数据等。

  • 可移植性:

    尽管每个数据库厂商实现他们自己的扩展,但厂商的每个新版本都符合ANSI/ISO SQL标准。标准兼容尽管很微妙,但也使大家能够更容易地从一个平台转移到另一个平台。

  • 稳定性:

    SQL几乎从不改变。虽然厂商实现他们自己的扩展并最终使其加入到 SQL标准,但SQL的核心没有改变。一旦理解了SQL的基础和关系原理,通常能够继续依赖这些知识,然后进一步添加那些本来依靠其他工具或开发者来实现的特性和功能。

  • 易于性能增益:

    数据库是一个容易做一些简单改变(添加一个索引,稍稍修改一个查询)并看到巨大性能改善的地方。

1.2 SQL语言的分类

  • DQL(Data Query Language):

    数据查询语言
    • select
  • DML(Data Manipulate Language):

    数据操作语言
    • insert
    • update
    • delete
  • DDL(Data Define Languge):

    数据定义语言
    • create
    • drop
    • alter
  • TCL(Transaction Control Language):

    事务控制语言
    • commit
    • rollback


2)DQL语言

2.1 基础查询

  • 语法:

    SELECT 要查询的东西
    【FROM 表名】;
    

注意查询前启用use该表:use 表名;

  • 特点:

    • ①通过select查询完的结果 ,是一个虚拟的表格,不是真实存在
    • ② 要查询的东西,可以是常量值、表达式、字段、函数
  • 常见使用:

    • 选择特定的列:

      SELECT department_id, location_id
      FROM departments;
      
    • 选择全部列:

      SELECT *
      FROM departments;
      # 按原表顺序显示
      
    • 查询常量、表达式、函数、方法:

      select 100;  
      # 注意:字符型和日期型的常量值必须用单引号引起来
      select 'john';
      select 100*98;
      select version(实参列表);
      
    • 起别名:

      # 方式一:使用AS
      select last_name AS 姓, first_name AS 名 
      FROM employees;
      # 方式二:使用空格
      select last_name  姓, first_name  名 
      FROM employees;
      # 别名含特殊符号的需要用"或'圈起来
      SELECT salary AS "out_put" 
      FROM employees
      
    • 去重:

      SELECT DISTINCT department_id 
      FROM employees;
      
    • 配合+号:

      # 两个操作数都为数值型,则做加法运算
      select 100+90;
      # 只要一方为字符型,试图将字符型数值转换成数值型,如果转换成功则继续做加法计算,如果转换失败,则将字符型数值转换成0
      # 只要其中一方为null,则结果肯定为null
      
    • 拼接:

      SELECT CONCAT('a','b','c') AS 结果;
      # 补充:IFNULL()
      select concat(ifnull(salary,0),id) from employees;
      

2.2 条件查询

条件查询:根据条件过滤原始表的数据,查询到想要的数据。

  • 语法:

    select 
    要查询的字段|表达式|常量值|函数
    from 
    表
    where 
    条件 ;
    

2.2.1 条件表达式:

示例:salary>10000
条件运算符:
	> < >= <= = != <>

2.2.2 逻辑表达式

示例:salary>10000 && salary<20000
逻辑运算符:
	and(&&):两个条件如果同时成立,结果为true,否则为false
	or(||):两个条件只要有一个成立,结果为true,否则为false
	not(!):如果条件成立,则not后为false,否则为true

2.2.3 模糊查询

示例:last_name like 'a%'
  • like 一般和通配符搭配使用:

    • % 任意多个字符,包含0个字符
    • _ 任意单个字符
    • \\ 转义字符
    • 自定义转义 ESCAPE
      WHERE last_name LIKE '_$_%' ESCAPE '$';
  • between and

    • 包含临界值
    • 临界值不能颠倒
  • in

    • 判断某字段的值是否属于in列表中的某一项
      WHERE job_id IN('IT_PROT','AD_VP');
    • in列表中的值类型必须统一或者兼容('123’与123兼容)
    • 不支持通配符
  • is null、is not null

    • =或者<>不能用于判断null值
    • 安全等于 <=>,也能判断null

2.3 排序查询

  • 语法:

    select
    要查询的东西
    from
    表
    where 
    条件
    order by 排序的字段|表达式|函数|别名 【asc|desc】
    
    • 按多个字段排序
      ORDER BY salary ASC,employee_id DESC;
    • 按函数排序
    • 按别名排序

  • 特点:

    • ASC代表升序,DESC代表降序,默认升序
    • 执行顺序:ORDER BY子句一般放在查询语句的最后面,limit子句除外

2.4 分组查询

  • 语法:

    select 查询的字段,分组函数
    from 表
    group by 分组的字段
    
    # 示例:
    SELECT column, group_function(column)
    FROM table
    WHERE condition
    GROUP BY group_by_condition
    ORDER BY column;
    
    • 注意:

      • 顺序是WHERE一定放在FROM后面,然后GROUP BY,最后ORDER BY
      • 查询列表必须特殊,要求是分组函数和group by后出现的字段
  • 特点:

    1、可以按单个字段分组
    2、和分组函数一同查询的字段最好是分组后的字段
    3、分组筛选:
    在这里插入图片描述

    • 分组函数做条件,那肯定是放在having子句中:
      SELECT MAX(salary),job_id
      FROM employees
      WHERE commission_pct IS NOT NULL
      GROUP BY job_id
      HAVING MAX(salary)>12000;		
      
    • 能用分组前筛选的,就优先考虑使用分组前筛选(考虑到性能相关的问题)

  • 常见的分组函数:

    • sum 求和、max 最大值、min 最小值、avg 平均值、count 计数
    • 分组函数作用于一组数据,并对一组数据返回一个值
    • 特点
      1、以上五个分组函数都忽略null值,除了count(*)
      2、sum和avg一般用于处理数值型,max、min、count可以处理任何数据类型
      3、都可以搭配distinct使用,用于统计去重后的结果
      4、count的参数可以支持:
      • 字段、*、常量值,一般放1
      • 建议使用 count(*)

4、可以按多个字段分组,字段之间用逗号隔开,没有顺序要求
```bash
SELECT AVG(salary),department_id,job_id
FROM employees
GROUP BY department_id,job_id;
```

5、可以支持排序
```bash
SELECT AVG(salary),department_id,job_id
FROM employees
GROUP BY department_id,job_id
ORDER BY AVG(salary) DESC; 
```

6、having后可以支持别名
```bash
SELECT COUNT(*),LENGTH(last_name) len_name
FROM employees
GROUP BY len_name
HAVING COUNT(*)>5;
```

2.5 多表连接查询(重点)

  • *笛卡尔乘积:

    在这里插入图片描述
    • 如何发生:如果连接条件省略或无效则会出现
    • 解决办法:添加上连接条件

  • *sql199标准(推荐):

    • 支持内连接+外连接(左外和右外)+交叉连接
    • 语法:
      select 字段,...
      from 表1
      【inner|left outer|right outer|cross】join 表2 on  连接条件
      【inner|left outer|right outer|cross】join 表3 on  连接条件
      【where 筛选条件】
      【group by 分组字段】
      【having 分组后的筛选条件】
      【order by 排序的字段或表达式】
      
      # 好处:语句上,连接条件和筛选条件实现了分离,简洁明了!
      

2.5.1 内连接

2.5.1.1 等值连接

SELECT NAME,boyname 
FROM boys,beauty
WHERE beauty.boyfriend_id = boys.id;

1、等值连接的结果 = 多个表的交集
2、n表连接,至少需要n-1个连接条件
3、多个表不分主次,没有顺序要求
4、一般为表起别名,提高阅读性和性能:

SELECT last_name,e.job_id,job_title 
FROM employees e,jobs j
WHERE e.`job_id`=j.`job_id`; 
  • 注意:如果为表起了别名,则查询的字段就不能使用原来的表名去限定

5、可以搭配前面介绍的所有子句使用,如:

  • 可以加筛选
SELECT city,department_name 	
FROM locations l,departments d
WHERE l.`location_id`=d.`location_id` 	
AND l.`city` LIKE '_o%'; 	
  • 可以加排序
  • 可以加分组
SELECT city,COUNT(*) 	
FROM locations l,departments d 	
WHERE l.`location_id`=d.`location_id` 	
GROUP BY city; 	```

2.5.1.2 非等值连接

SELECT salary,grade_level
FROM employees e,job_grades j
WHERE e.`salary` BETWEEN j.`lowest_sal` AND j.`highest_sal`;

2.5.1.3 自连接

SELECT e1.last_name,e2.last_name
FROM employees e1,employees e2
WHERE e1.`manager_id`=e2.`employee_id`;

2.5.2 外连接

  • 内连接 [inner] join on

  • 左外连接

    • 语法:left 【outer】 join on
    SELECT b.name
    FROM beauty b
    LEFT JOIN boys 
    ON b.`boyfriend_id`=boys.id
    WHERE boys.id IS NULL;
    
  • 右外连接

    • 语法:right 【outer】 join on

  • 全连接

    • 语法:full 【outer】 join on
    • 全外连接=内连接的结果+表1中有但表2没有的+表2中有但表1中没有的
  • 总结:

在这里插入图片描述
在这里插入图片描述

特点:

1、外连接的查询结果为主表中的所有记录

  • 如果从表中有和它匹配的,则显示匹配的值
  • 如果从表中没有和它匹配的,则显示NULL
  • 外连接查询结果=内连接结果+主表中有而从表没有的记录

2、左外连接,left join左边的是主表
3、右外连接,right join右边的是主表
4、左外后右外交换两个表的顺序,可以实现同样的效果

2.5.3 交叉连接(cross)

就是笛卡尔乘积。


2.6 子查询

一条查询语句中又嵌套了另一条完整的select语句,其中被嵌套的select语句,称为子查询或内查询。在外面的查询语句,称为主查询或外查询。

2.6.1 按功能(结果集的行列数)不同分类

  • 标量子查询(结果集只有一行一列)
  • 列子查询(结果集只有一列多行)
  • 行子查询(结果集有一行多列)
  • 表子查询(结果集一般为多行多列)

2.6.2 按子查询出现的位置分类

  • select后面

    仅仅支持标量子查询

    SELECT d.*,(
    	SELECT COUNT(*)
    	FROM employees e
    	WHERE e.department_id=d.`department_id`
    )
    FROM departments d;
    
  • from后面

    支持表子查询

    SELECT ag_dep.*,j.grade_level
    FROM (
    	SELECT department_id,AVG(salary) ag
    	FROM employees
    	GROUP BY department_id
    ) AS ag_dep
    INNER JOIN job_grades j
    ON ag_dep.ag BETWEEN j.lowest_sal AND j.highest_sal;
    
    • 将子查询结果充当一张表,要求起别名
  • where或having后面

    • 标量子查询:

      SELECT MIN(salary),department_id
      FROM employees
      GROUP BY department_id
      HAVING MIN(salary)>(SELECT MIN(salary)
      FROM employees e,departments d
      WHERE d.`department_id`=50);
      
    • 列子查询

    • 行子查询

  • exists后面(相关子查询)

    • 支持表子查询

    • 语法:
      exists(完整的查询语句)
      结果:1或0

    • 子查询用到了主查询:

      SELECT department_name
      FROM departments d
      WHERE EXISTS (
      	SELECT employee_id 
      	FROM employees e
      	WHERE e.`department_id`=d.`department_id`
      );
      

2.6.3 特点:

1、子查询都放在小括号内

2、子查询可以放在from后面、select后面、where后面、having后面,但一般放在条件的右侧

3、子查询优先于主查询执行,主查询使用了子查询的执行结果

4、子查询根据查询结果的行数不同分为以下两类:

  • ① 单行子查询
    • 结果集只有一行
    • 一般搭配单行操作符使用:> < = <> >= <=
    • 非法使用子查询的情况:
      a、子查询的结果为一组值
      b、子查询的结果为空
  • ② 多行子查询
    • 结果集有多行
    • 一般搭配多行操作符使用:any、all、in、not in
      • in: 属于子查询结果中的任意一个就行
      • any和all往往可以用其他查询代替

2.7 分页查询

  • 应用场景:

    实际的web项目中需要根据用户的需求提交对应的分页查询的sql语句。

  • 语法:

    select 字段|表达式,...
    from 表
    【where 条件】
    【group by 分组字段】
    【having 条件】
    【order by 排序的字段】
    limit 【起始的条目索引,】条目数;
    # 起始索引从0开始
    
  • 特点:

    1.起始条目索引从0开始
    2.limit子句放在查询语句的最后
    3.公式:

    select * from  表 limit (page-1)*sizePerPage,sizePerPage
    # 假如:
    #	每页显示条目数sizePerPage
    #	要显示的页数 page
    

2.8 联合查询

  • 语法:

    select 字段|常量|表达式|函数 【from 表】 【where 条件】 union 【all】
    select 字段|常量|表达式|函数 【from 表】 【where 条件】 union 【all】
    select 字段|常量|表达式|函数 【from 表】 【where 条件】 union  【all】
    .....
    select 字段|常量|表达式|函数 【from 表】 【where 条件】
    
  • 特点:

    1、多条查询语句的查询的列数必须是一致的
    2、多条查询语句的查询的列的类型几乎相同
    3、union代表去重,union all代表不去重


2.9 小结

在这里插入图片描述
1、SELECT 标识选择哪些列。
2、FROM 标识从哪个表中选择。
3、使用WHERE子句,将不满足条件的行过滤掉(WHERE子句紧随 FROM 子句)。
4、使用GROUP BY子句将表中的数据分成若干组。
5、使用 HAVING 过滤分组。
6、使用 ORDER BY 子句排序。
7、分页查询。

  • 注意

    • SQL 语言大小写不敏感。
    • SQL 可以写在一行或者多行
    • 关键字不能被缩写也不能分行
    • 各子句一般要分行写
    • 使用缩进提高语句的可读性
  • 列的别名

    紧跟列名,也可以在列名和别名之间加入关键字‘AS’,别名使用双引号,以便在别名中包含空格或特殊的字符并区分大小写
    在这里插入图片描述

  • 比较运算
    在这里插入图片描述

  • 其他比较运算
    在这里插入图片描述

  • 逻辑运算
    在这里插入图片描述

以上是关于数据库SQL语言以及DQL的学习的主要内容,如果未能解决你的问题,请参考以下文章

Mysql学习---SQL语言的四大分类

第6讲:SQL语句之DQL类型的数据查询语言

Mysql DBA 高级运维学习笔记-sql语言介绍及分类

SQL语言分类DQL,DML,DDL,DCL

MySql学习笔记之DQL常用查询

MySQL 基础 SQL -- DQL 数据查询语言(基础查询(字段别名) where条件查询(比较运算符逻辑运算符) 聚合函数分组查询 排序查询分页查询DQL语句执行顺序)