数据库(三)

news2024/11/29 0:36:56

第三章 MySQL库表操作

3.1 SQL语句基础

3.1.1 SQL简介

SQL:结构化查询语言(Structured Query Language),在关系型数据库上执行数据操作、数据检索以及数据维护的标准语言。使用SQL语句,程序员和数据库管理员可以完成如下的任务。

  • 改变数据库的结构

  • 更改系统的安全设置

  • 增加用户对数据库或表的许可权限

  • 在数据库中检索需要的信息

  • 对数据库的信息进行更新

3.1.2 SQL语句分类

MySQL致力于支持全套ANSI/ISO SQL标准。在MySQL数据库中,SQL语句主要可以划分为以下几类:

DDL(Data Definition Language):数据定义语言,定义对数据库对象(库、表、列、索引)的操作。CREATE、DROP、ALTER、RENAME、 TRUNCATE等。 DML(Data Manipulation Language): 数据操作语言,定义对数据库记录的操作。INSERT、DELETE、UPDATE等。

DQL(Data Query Language)数据查询语言:SELECT语句。

DCL(Data Control Language): 数据控制语言,定义对数据库、表、字段、用户的访问权限和安全级别。GRANT、REVOKE等。 TCL(Transaction Control):事务控制。COMMIT、ROLLBACK、SAVEPOINT等。

注:可以使用help查看这些语句的帮助信息。

3.1.3 SQL语句的书写规范

  • 在数据库系统中,SQL语句不区分大小写(建议用大写) 。

  • 但字符串常量区分大小写。

  • SQL语句可单行或多行书写,以“;”结尾。

  • 关键词不能跨多行或简写。

  • 用空格和缩进来提高语句的可读性。

  • 子句通常位于独立行,便于编辑,提高可读性。

sql语句注释:
(1)单行注释:“--” 
mysql> -- select user,host from mysql.user;
mysql> select user from mysql.user -- where user='root';
    -> ;
+------------------+
| user             |
+------------------+
| mysql.infoschema |
| mysql.session    |
| mysql.sys        |
| root             |
+------------------+
(2)多行注释:/* text */
mysql> select user from mysql.user /*
   /*> where user='root'
   /*> */
    -> ;
+------------------+
| user             |
+------------------+
| mysql.infoschema |
| mysql.session    |
| mysql.sys        |
| root             |
+------------------+ 
​

3.2 数据库操作

1、查看

语法:SHOW DATABASES [LIKE wild];

wild可以使用"%"和"_"通配符。

%表示匹配任意零个或多个的任意字符。

_表示单个任意字符。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
Information_schema:主要存储了系统中的一些数据库对象信息:如用户表信息、列信息、权限信息、字符集信息、分区信息等。(数据字典表)
performance_schema:主要存储数据库服务器的性能参数
mysql:存储了系统的用户权限信息及帮助信息。        
sys: 5.7新增,之前版本需要手工导入。这个库是通过视图的形式把information_schema和performance_schema结合起来,查询出更加令人容易理解的数据。      
test:系统自动创建的测试数据库,任何用户都可以使用。
mysql> show databases like '__s%';
+-----------------+
| Database (__s%) |
+-----------------+
| mysql           |
| sys             |
+-----------------+

2、创建

语法:CREATE DATABASE [IF NOT EXISTS] 数据库名;

用给定的名字创建一个数据库,如果数据库已经存在,则报错。

#查看创建数据库的语句:SHOW CREATE DATABASE <数据库名>;
mysql> show create database mysql;
+----------+---------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database                                                           |
+----------+---------------------------------------------------------------------------------------------------------------------------------+
| mysql    | CREATE DATABASE `mysql` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+----------+---------------------------------------------------------------------------------------------------------------------------------+
mysql> create database chap03;
Query OK, 1 row affected (0.00 sec)
​
mysql> show create database chap03;
+----------+----------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database                                                         |
+----------+----------------------------------------------------------------------------------------------------------------------------------+
| chap03   | CREATE DATABASE `chap03` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+----------+----------------------------------------------------------------------------------------------------------------------------------+

3、删除

语法:DROP DATABASE [IF EXISTS]数据库名;

删除数据库中得所有表和数据库(慎用)

mysql> drop database chap03;

4、切换

语法:USE 数据库名;

把指定数据库作为默认(当前)数据库使用,用于后续语句。

mysql> use mysql
# 查看当前连接的数据库
mysql> select database();
+------------+
| database() |
+------------+
| mysql      |
+------------+
#设置提示符显示当前数据库名称
[root@mysql8-0-30 mysql]# vim /etc/my.cnf.d/mysql-server.cnf
[mysql]
prompt=mysql8.0 [\\d]>
[root@mysql8-0-30 mysql]# systemctl restart mysqld
[root@mysql8-0-30 mysql]# mysql -uroot -pAdmin123! mysql
mysql8.0 [mysql]>

5、执行系统命令

语法:system 命令

mysql> system date
2023年 02月 06日 星期一 15:57:52 CST
mysql> system ls /
afs  boot  etc   lib    media  opt   root  sbin  sys  usr
bin  dev   home  lib64  mnt    proc  run   srv   tmp var

3.3 MySQL 字符集

MySQL字符集包括字符集(CHARACTER)和校对规则(COLLATION)两个概念:字符集(CHARACTER)是一套编码,校对规则(COLLATION)是在字符集内用于比较字符的一套规则。

mysql字符集:
    latin1支持西欧字符、希腊字符等
    gbk支持中文简体字符
    big5支持中文繁体字符
    utf8几乎支持世界所有国家的字符。
    utf8mb4是真正意义上的utf-8
#查看字符集
mysql> show variables like 'character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8mb3                    |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
#修改mysql默认字符集
1.在[mysqld]下添加
    character-set-server=utf8
    init_connect = 'SET NAMES utf8'
2.在[client]下添加
    default-character-set=utf8
3. 5.8开始,官方建议使用utf8mb4。

| character_set_client | utf8mb4 | mysql客户端字符集 | character_set_connection | utf8mb4 | 数据通信链路字符集,当mysql客户端向服务器发送请求时,客户端的请求数据以该字符集进行编码。 | character_set_database | utf8mb4 | 数据库字符集 | character_set_filesystem | binary | MySQL服务器文件系统字符集,该值是固定的binary | character_set_results | utf8mb4 | 结果集的字符集,MySQL服务器向mysql客户端返回执行结果时,执行结果以该字符集进行编码。 | character_set_server | utf8mb4 | mysql服务器实例字符集 | character_set_system | utf8mb3 | 元数据(字段名、表名、数据库名等)的字符集 | character_sets_dir | /usr/share/mysql/charsets/ | 字符集安装的目录

#查看当前mysql服务实例支持的校对规则
mysql> show collation;
| Collation                   | Charset  | Id  | Default | Compiled | Sortlen | Pad_attribute |
| armscii8_bin                | armscii8 |  64 |         | Yes      |       1 | PAD SPACE     |

Collation 字符集校对规则名称。MySQL校对规则名称是:以对应的字符集名称开头,以国家名居中(或以general居中),以ci、cs或bin结尾。【ci表示大小写不敏感,cs表示大小写敏感,bin表示按二进制编码值比较。】 Charset 与字符集校对规则关联的字符集名称 Id 字符集校对规则编号 Default 是不是对应字符集默认的校对规则 Compiled 是否有将此字符集校对规则集成到服务器中 Sortlen 这个与字符串表示的字符集所需要的内存数量有关 Pad_attribute 控制字符串尾部空格处理方式。PAD SPACE:在排序和比较运算中,忽略字符串尾部空格;NO PAD:在排序和比较运算中,字符串尾部空格当成普通字符,不能忽略。

3.3.1 utf8和utf8mb4的区别

MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。好在utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf8也就够了。

既然utf8能够存下大部分中文汉字,那为什么还要使用utf8mb4呢? 原来mysql支持的 utf8 编码最大字符长度为 3 字节,如果遇到 4 字节的宽字符就会插入异常了。三个字节的 UTF-8 最大能编码的 Unicode 字符是 0xffff,也就是 Unicode 中的基本多文种平面(BMP)。也就是说,任何不在基本多文本平面的 Unicode字符,都无法使用 Mysql 的 utf8 字符集存储。包括 Emoji 表情(Emoji 是一种特殊的 Unicode 编码,常见于 ios 和 android 手机上),和很多不常用的汉字,以及任何新增的 Unicode 字符,如表情等等(utf8的缺点)。

因此在8.0之后,建议大家使用utf8mb4这种编码。

3.4 数据库对象

数据库对象的命名规则:

  • 必须以字母开头

  • 可包括数字和特殊字符(_和$)

  • 不要使用MySQL的保留字

  • 同一Schema下的对象不能同名

3.5 表的基本操作

3.5.1 创建表

数据表的每行称为一条记录(record);每一列称为一个字段(field)【列之间以英文逗号隔开】。

简单语法:在当前数据库中创建一张表
    CREATE TABLE 表名(
    列名 列数据类型,
    列名 列数据类型
    );
mysql8.0 [chap03]>create table t1(id int,name char(30));

3.5.2 数据类型

在 MySQL 中,有三种主要的类型:文本、数值和日期/时间类型。

文本类型:

数据类型描述
CHAR(size)保存固定长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的长度。最多 255 个字符。
VARCHAR(size)保存可变长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的最大长度。最多 255 个字符。 注释:如果值的长度大于 255,则被转换为 TEXT 类型。
TINYTEXT存放最大长度为 255 个字符的字符串。
TEXT存放最大长度为 65,535 个字符的字符串。
BLOB用于 BLOBs (Binary Large OBjects),二进制形式的长文本数据。存放最多 65,535 字节的数据。
MEDIUMTEXT存放最大长度为 16,777,215 个字符的字符串。
MEDIUMBLOB用于 BLOBs (Binary Large OBjects),二进制形式的中等长度文本数据。存放最多 16,777,215 字节的数据。
LONGTEXT存放最大长度为 4,294,967,295 个字符的字符串。
LONGBLOB用于 BLOBs (Binary Large OBjects),二进制形式的极大文本数据。存放最多 4,294,967,295 字节的数据。
ENUM(x,y,z,etc.)允许你输入可能值的列表。可以在 ENUM 列表中列出最大 65535 个值。如果列表中不存在插入的值,则插入空值。 注释:这些值是按照你输入的顺序存储的。 可以按照此格式输入可能的值: ENUM('X','Y','Z')
SET与 ENUM 类似, SET 最多只能包含 64 个列表项,不过 SET 可存储一个以上的值。

数值类型:

类型用途存储需求范围(有符号)范围(无符号)
TINYINT小整数值1 Bytes(-128,127)(0,255)
SMALLINT大整数值2 Bytes(-32 768,32 767)(0,65 535)
MEDIUMINT大整数值3 Bytes(-8 388 608,8 388 607)(0,16 777 215)
INT或INTEGER大整数值4 Bytes(-2 147 483 648,2 147 483 647)(0,4 294 967 295)
BIGINT极大整数值8 Bytes(-9,223,372,036,854,775,808,9 223 372 036 854 775 807)(0,18 446 744 073 709 551 615)
类型用途存储需求范围(有符号)范围(无符号)
FLOAT(size,d)带有浮动小数点的小数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。4Byte(-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38)0,(1.175 494 351 E-38,3.402 823 466 E+38)
DOUBLE(size,d)带有浮动小数点的大数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。8Byte(-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)
DECIMAL(size,d)作为字符串存储的 DOUBLE 类型,允许固定的小数点。(size+2)Byte

注意:这些数值类型拥有额外的选项 UNSIGNED。通常,整数可以是负数或正数。如果添加 UNSIGNED属性,那么范围将从 0 开始,而不是某个负数。

日期/时间类型:

数据类型存储需求描述
DATE3Bytes日期。格式: YYYY-MM-DD 注释:支持的范围是从 '1000-01-01' 到 '9999-12-31'
DATETIME8Bytes日期和时间的组合。格式: YYYY-MM-DD HH:MM:SS 注释:支持的范围是'1000-01-01 00:00:00' 到 '9999-12- 31 23:59:59'
TIMESTAMP4Bytes时间戳。 TIMESTAMP 值使用 Unix 纪元('1970-01-01 00:00:00' UTC) 至今的描述来存储。格式: YYYY-MM-DD HH:MM:SS 注释:支持的范围是从 '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC
TIME3Bytes时间。格式: HH:MM:SS 注释:支持的范围是从 '-838:59:59' 到 '838:59:59'
YEAR1Bytes2 位或 4 位格式的年。 注释: 4 位格式所允许的值: 1901 到 2155。 2 位格式所允许的值: 70 到69,表示从 1970 到 2069

常用数据类型:

3.5.3 查看表

#查看某数据库中的所有表
语法:SHOW TABLES[FROM 数据库名][LIKE wild];
mysql8.0 [chap03]>show tables from mysql;
#显示当前数据库中已有的数据表的信息【结构和创建信息】
1、语法:{DESCRIBE|DESC} 表名[列名];
mysql8.0 [chap03]>describe mysql.user;
mysql8.0 [chap03]>desc mysql.user;
2、语法:show columns from 表名称;
mysql8.0 [chap03]>show columns from mysql.user;
#查看数据表中各列的信息
语法:SHOW CREATE TABLE 表名\G
mysql8.0 [chap03]>show create table mysql.user\G
说明:\G表示向mysql服务器发送命令,垂直显示结果

3.5.4 删除表

#删除指定的表
语法:DROP TABLE [IF EXISTS] 表名;
mysql8.0 [chap03]>drop table  t1;

3.5.5 修改表的结构

mysql8.0 [chap03]>create table t1(id int,name char(30));
mysql8.0 [chap03]>desc t1;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int      | YES  |     | NULL    |       |
| name  | char(30) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
#修改列类型:ALTER TABLE 表名 MODIFY 列名 列类型;
mysql8.0 [chap03]>alter table t1 modify name varchar(30);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
​
mysql8.0 [chap03]>desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | YES  |     | NULL    |       |
| name  | varchar(30) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
    
#增加列:ALTER TABLE 表名 ADD 列名 列类型;
mysql8.0 [chap03]>alter table t1 add bir date;  
#删除列:ALTER TABLE 表名 DROP 列名;
mysql8.0 [chap03]>alter table t1 drop bir;  
#修改列名:ALTER TABLE 表名 CHANGE 旧列名 新列名 列类型;
mysql8.0 [chap03]>alter table t1 change id user_id int;
#更改表名:
方式1:ALTER TABLE 表名 RENAME 新表名;
方式2:RENAME TABLE 表名 TO 新表名;
mysql8.0 [chap03]>alter table t1 rename t2;
mysql8.0 [chap03]>rename table t2 to t3;
mysql8.0 [chap03]>show tables;
+------------------+
| Tables_in_chap03 |
+------------------+
| t3               |
+------------------+

3.5.6 复制表的结构

#复制一个表结构的实现方法有两种:
方法1:在create table语句的末尾添加like子句,可以将源表的表结构复制到新表中,语法:create table 新表名 like 源表
mysql8.0 [chap03]>create table t4 like t3;
​
方法2:在create table语句的末尾添加一个select语句,可以实现表结构的复制,甚至可以将源表的表记录拷贝到新表中。
语法:create table 新表名 select * from 源表
mysql8.0 [chap03]>create table t5 select * from t4;
​
方法3:如果已经存在一张结构一致的表,复制数据
语法:insert into 表名 select * from 原表;

3.5.7 表的约束

约束是在表上强制执行的数据校验规则。约束主要用于保证数据库的完整性。当表中数据有相互依赖性时,可以保护相关的数据不被删除。

可以在创建表时规定约束(通过 CREATE TABLE 语句),或者在表创建之后通过 ALTER TABLE 语句规定约束。

  • 根据约束数据列的限制,约束可分为:

    • 单列约束:每个约束只约束一列。

    • 多列约束:每个约束可约束多列数据。

  • 根据约束的作用范围,约束可分为:

    • 列级约束:只能作用在一个列上,跟在列的定义后面,语法:列定义 约束类型

    • 表级约束:可以作用在多个列上,不与列一起,而是单独定义

      语法:[CONSTRAINT 约束名] 约束类型(列名)
      约束名的取名规则,推荐采用:表名_列名_约束类型
      例如:alter table 表名 add constraint 约束名 约束类型(要约束的列名)
      表级约束类型有四种:主键、外键、唯一、检查
  • 根据约束起的作用,约束可分为:

    NOT NULL 非空约束,规定某个字段不能为空
    UNIQUE 唯一约束,规定某个字段在整个表中是唯一的
    PRIMARY KEY 主键(非空且唯一)约束
    FOREIGN KEY 外键约束
    CHECK 检查约束
    DEFAULT 默认值约束

表的约束示例:

1、非空约束(NOT NULL)

列级约束,只能使用列级约束语法定义。确保字段值不允许为空。

mysql8.0 [chap03]>create table t6(
    -> id int,
    -> name char(30) not null
    -> );
注意:所有数据类型的值都可以是NULL,空字符串不等于NULL,0也不等于NULL。
#删除NOT NULL约束,alter table 表名 modify 列名 类型;
mysql8.0 [chap03]>alter table t6 modify name char(30);

2、唯一约束(UNIQUE)

  • 唯一性约束条件确保所在的字段或者字段组合不出现重复值。

  • 唯一性约束条件的字段允许出现多个NULL。

  • 同一张表内可建多个唯一约束。

  • 唯一约束可由多列组合而成。

  • 建唯一约束时MySQL会为之建立对应的索引。

  • 如果不给唯一约束起名,该唯一约束默认与列名相同。

mysql8.0 [chap03]>create table t7(
    -> id int unique,
    -> name char(30) not null
    -> );
​
mysql8.0 [chap03]>desc t7;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int      | YES  | UNI | NULL    |       |
| name  | char(30) | NO   |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)t 
​
#删除UNIQUE约束,alter table 表名 drop index 唯一约束名;
mysql8.0 [chap03]>alter table t7 drop index id;

3、主键约束(PRIMARY KEY)

主键从功能上看相当于非空且唯一,一个表中只允许一个主键,主键是表中唯一确定一行数据的字段,主键字段可以是单字段或者是多字段的组合。 当建立主键约束时,MySQL为主键创建对应的索引。

mysql8.0 [chap03]>mysql8.0 [chap03]>create table t8(
    -> id int primary key,
    -> name char(30) not null
    -> );
Query OK, 0 rows affected (0.06 sec)
​
mysql8.0 [chap03]>desc t8;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int      | NO   | PRI | NULL    |       |
| name  | char(30) | NO   |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
#自动增长:auto_increment :自动增长,为新的行产生唯一的标识,一个表只能有一个auto_increment,且该属性必须为主键的一部分。auto_increment的属性可以是任何整数类型。
mysql8.0 [chap03]>create table t_auto(id int primary key auto_increment);
​
#删除PRIMARY KEY约束,alter table 表名 drop primary key;
mysql8.0 [chap03]>alter table t8 drop primary key;

4、外键约束(FOREIGN KEY)

外键是构建于一个表的两个字段或者两个表的两个字段之间的关系,外键确保了相关的两个字段的两个关系。 子(从)表外键列的值必须在主表参照列值的范围内,或者为空(也可以加非空约束,强制不允许为空)。 当主表的记录被子表参照时,主表记录不允许被删除。 外键参照的只能是主表主键或者唯一键,保证子表记录可以准确定位到被参照的记录。

语法:FOREIGN KEY (外键列名)REFERENCES 主表(参照列)
​
mysql8.0 [chap03]>create table tb_dept(dept_id int primary key,name char(30));
mysql8.0 [chap03]>create table tb_employee(employee_id int primary key,name char(30),dept_id int,foreign key(dept_id)  references tb_dept(dept_id));
#删除FOREIGN KEY约束,alter table 表名 drop foreign key 约束名;
mysql8.0 [chap03]>show create table tb_employee\G
*************************** 1. row ***************************
       Table: tb_employee
Create Table: CREATE TABLE `tb_employee` (
  `employee_id` int NOT NULL,
  `name` char(30) DEFAULT NULL,
  `dept_id` int DEFAULT NULL,
  PRIMARY KEY (`employee_id`),
  KEY `dept_id` (`dept_id`),
  CONSTRAINT `tb_employee_ibfk_1` FOREIGN KEY (`dept_id`) REFERENCES `tb_dept` (`dept_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
mysql8.0 [chap03]>alter table tb_employee drop foreign key tb_employee_ibfk_1;

5、检查约束(CHECK )

# 注意检查约束在8.0之前,MySQL默认但不会强制的遵循check约束(写不报错,但是不生效,需要通过触发器完成),8之后就开始正式支持这个约束了。
mysql8.0 [chap03]>create table t9(
    -> id int,
    -> age int check(age > 18),
    -> gender char(1) check(gender in ('M','F'))
    -> );
#删除检查约束
mysql8.0 [chap03]>show create table t9;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t9    | CREATE TABLE `t9` (
  `id` int DEFAULT NULL,
  `age` int DEFAULT NULL,
  `gender` char(1) DEFAULT NULL,
  CONSTRAINT `t9_chk_1` CHECK ((`age` > 18)),
  CONSTRAINT `t9_chk_2` CHECK ((`gender` in (_utf8mb4'M',_utf8mb4'F')))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
mysql8.0 [chap03]>alter table t9 drop check t9_chk_2;

6、 默认值约束(DEFAULT)

可以使用default关键字设置每一个字段的默认值。

#设置默认值约束
mysql8.0 [chap03]>create table t10(
    -> id int unique,
    ->  name char(30) not null,
    -> gender char(1) default 'M',
    -> primary key(id)
    -> );
#删除默认值约束
mysql8.0 [chap03]>alter table t10 modify gender char;

3.5.8 数据库字典

由information_schema数据库负责维护:
​
tables-存放数据库里所有的数据表、以及每个表所在数据库。
schemata-存放数据库里所有的数据库信息
views-存放数据库里所有的视图信息。
columns-存放数据库里所有的列信息。
triggers-存放数据库里所有的触发器。
routines-存放数据库里所有存储过程和函数。
key_column_usage-存放数据库所有的主外键
table_constraints-存放各个表的约束。
statistics-存放了数据表的索引。

3.5.9 存储引擎

MySQL中的数据用各种不同的技术存储在文件(或者内存)中, 每种技术都使用不同的存储机制、 索引技巧、 锁定水平。这些不同的技术以及配套的相关功能在MySQL中被称作存储引擎(也称作表类型)。

数据库存储引擎是数据库底层软件组件,数据库管理系统使用数据引擎进行创建、查询、更新和删除数据操作。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎还可以获得特定的功能。

现在许多数据库管理系统都支持多种不同的存储引擎。MySQL 的核心就是存储引擎。

InnoDB 事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键。应用于对事务的完整性要求高,在并发条件下要求数据的一致性的情况。 MySQL 5.5.5 之后,InnoDB 作为默认存储引擎。

MyISAM 是基于 ISAM 的存储引擎,并对其进行扩展,是在 Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM 拥有较高的插入、查询速度,但不支持事务。应用于以读写操作为主, 很少更新 、 删除 , 并对事务的完整性、 并发性要求不高的情况。

MEMORY 存储引擎将表中的数据存储到内存中,为查询和引用其他数据提供快速访问。

MEMORY:表的数据存放在内存中,访问效率高 ,但一旦服务关闭,表中的数据全部丢失。

MERGE: 是一组MyISAM表的组合。 可以突破对单个MyISAM表大小的限制, 并提高访问效率。

默认情况下, 创建表不指定表的存储引擎, 则会使用配置文件my.cnf中 default-storage-engine=InnoDB指定的存储引擎。

#在创建表时, 可以指定表的存储引擎:
CREATE TABLE (...)  ENGINE=InnoDB;  
#完整的创建表的命令语法
CREATE TABLE 表名 (
    列名 列类型 [primary key AUTO_INCREMENT] [DEFAULT 默认值][列约束]
    ...
    [表约束]
) [ENGINE=存储引擎类型] [DEFAULT] CHARSET=字符集;
​
列类型: 该列的数据的存储类型
AUTO_INCREMENT: 自动增长,只能是数值类型的列
DEFAULT 默认值:设置该列的默认值
列约束:对列的一些限制
ENGINE: 表类型, 也叫表的存储引擎
CHARSET: 设置表的字符集

3.5.10 表物理存储结构

表的物理存储结构:

MyISAM(一种引擎)的表:
mysql8.0 [chap03]>create table test(id int)engine=myisam;
[root@node1 ~]# cd /var/lib/mysql/chap03/
[root@mysql8-0-30 chap03]# ll test*
#表结构元数据
-rw-r-----. 1 mysql mysql 1630  2月  7 01:21 test_414.sdi
# 数据信息文件,存储数据信息
-rw-r-----. 1 mysql mysql    0  2月  7 01:21 test.MYD
# 索引信息文件,index
-rw-r-----. 1 mysql mysql 1024  2月  7 01:21 test.MYI
​
InnoDB(默认的存储引擎)的表:
[root@node2 employess]# ls -l t4*
#innodb引擎开启了独立表空间产生的存放该表的数据和索引的文件   
-rw-r----- 1 mysql mysql 98304 7月  16 20:32 t4.ibd
ttt

3.6 MySQL用户授权

3.6.1 密码策略

#mysql8.0会生成临时密码,查看临时密码
[root@mysql8-0-30 ~]# awk '/temporary password/ {print $NF}' /var/log/mysqld.log
[root@mysql8-0-30 ~]# grep 'password' /var/log/mysqld.log
#查看数据库当前密码策略:
mysql8.0 [chap03]>show VARIABLES like "%password%";

3.6.2 用户授权和撤销授权

MySql8有新的安全要求,不能像之前的版本那样一次性创建用户并授权。需要先创建用户,再进行授权操作。

mysql8.0 [chap03]>grant all privileges on *.* to 'xiaoming'@'%';
ERROR 1410 (42000): You are not allowed to create a user with GRANT

1、创建用户

#创建新用户,语法:create user 'username'@'host' identified by 'password';
说明:username为自定义的用户名,host为客户端的域名或者IP,如果host为'%'时表示为任意IP,password为密码。
mysql8.0 [mysql]>create user xiaoming@'%' identified by '123';
mysql8.0 [mysql]>select user,host,authentication_string from mysql.user;
#删除用户
mysql8.0 [mysql]>drop user xiaoming@'%';
#注意,如果删除用户时显示如下提示,需要执行该语句【mysql8.0 [(none)]>grant system_user on *.* to root@'%';】
mysql8.0 [mysql]>drop user xiaoming;
ERROR 1227 (42000): Access denied; you need (at least one of) the SYSTEM_USER privilege(s) for this operation

2、授权和回收权限

授予权限的原则: (1)只授予能满足需要的最小权限 ,防止用户干坏事。比如用户只是需要查询,那就只给 select 权限就可以了,不要给用户赋予update 、 insert 或者 delete 权限 (2)创建用户的时候限制用户的登录主机 ,一般是限制成指定 IP 或者内网 IP 段。 (3)为每个用户设置满足密码复杂度的密码 。 (4)定期清理不需要的用户 ,回收权限或者删除用户。

#查看授予用户的权限
mysql8.0 [mysql]>show grants;
mysql8.0 [mysql]>show grants for root@'%';
mysql8.0 [mysql]>select * from mysql.user;
#查看某个用户从哪个服务器ip地址连接对某个数据库的操作权限,这三个字段的组合构成了db表的主键。
mysql8.0 [mysql]>select * from mysql.db;
#查看用户对单个表的权限
mysql8.0 [mysql]>select * from mysql.tables_priv;

授权语法:grant 权限列表 on 库名.表名 to 用户名@'主机' [with GRANT option];

mysql用户常用权限列表说明
all 或者all privileges授予用户所有权限
create授予用户创建新数据库和表的权限
drop授予用户删除数据库和表的权限
delete授予用户删除表中的行的权限
alter授予用户修改表结构的权限
insert授予用户在表中插入行(add)的权限
select授予用户运行select命令以从表中读取数据的权限
update授予用户更新表中的数据的权限
mysql8.0 [mysql]>grant all privileges on *.* to 'xiaoming'@'%' with grant option;
mysql8.0 [mysql]>flush privileges;
#说明:*.*中第一个*表示所有数据库,第二个*表示所有数据表;with grant option表示授予xiaoming用户grant命令(该命令可以给别的用户授权)的权限
mysql8.0 [mysql]>select user,grant_priv from mysql.user;
+------------------+------------+
| user             | grant_priv |
+------------------+------------+
| root             | Y          |
| xiaoming         | Y          |
| mysql.infoschema | N          |
| mysql.session    | N          |
| mysql.sys        | N          |
+------------------+------------+
mysql8.0 [mysql]>create user xiaohong@'%' identified by '123';
Query OK, 0 rows affected (0.01 sec)
​
mysql8.0 [mysql]>select select_priv,user from mysql.user;
+-------------+------------------+
| select_priv | user             |
+-------------+------------------+
| Y           | root             |
| N           | xiaohong         |
| Y           | xiaoming         |
| Y           | mysql.infoschema |
| N           | mysql.session    |
| N           | mysql.sys        |
+-------------+------------------+
6 rows in set (0.00 sec)
​
mysql8.0 [mysql]>grant select on mysql.user to xiaohong@'%';
mysql8.0 [mysql]>select * from tables_priv;
+-----------+-------+---------------+------------+--------------------+---------------------+------------+-------------+
| Host      | Db    | User          | Table_name | Grantor            | Timestamp           | Table_priv | Column_priv |
+-----------+-------+---------------+------------+--------------------+---------------------+------------+-------------+
| %         | mysql | xiaohong      | user       | xiaoming@localhost | 2023-02-08 00:56:32 | Select     |             |
| localhost | mysql | mysql.session | user       | boot@              | 2023-02-05 18:30:53 | Select     |             |
| localhost | sys   | mysql.sys     | sys_config | root@localhost     | 2023-02-05 18:30:53 | Select     |             |
+-----------+-------+---------------+------------+--------------------+---------------------+------------+-------------+
mysql8.0 [mysql]>select * from db where user='xiaohong';
+------+--------+----------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+-----------------------+------------------+------------------+----------------+---------------------+--------------------+--------------+------------+--------------+
| Host | Db     | User     | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Grant_priv | References_priv | Index_priv | Alter_priv | Create_tmp_table_priv | Lock_tables_priv | Create_view_priv | Show_view_priv | Create_routine_priv | Alter_routine_priv | Execute_priv | Event_priv | Trigger_priv |
+------+--------+----------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+-----------------------+------------------+------------------+----------------+---------------------+--------------------+--------------+------------+--------------+
| %    | chap03 | xiaohong | Y           | N           | N           | N           | N           | N         | N          | N               | N          | N          | N                     | N                | N                | N              | N                   | N                  | N            | N          | N            |
+------+--------+----------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+-----------------------+------------------+------------------+----------------+---------------------+--------------------+--------------+------------+--------------+
mysql8.0 [mysql]>show grants for xiaohong@'%';
+--------------------------------------------------+
| Grants for xiaohong@%                            |
+--------------------------------------------------+
| GRANT USAGE ON *.* TO `xiaohong`@`%`             |
| GRANT SELECT ON `chap03`.* TO `xiaohong`@`%`     |
| GRANT SELECT ON `mysql`.`user` TO `xiaohong`@`%` |
+--------------------------------------------------+
#usage:连接(登录)权限,建立一个用户,就会自动授予usage权限(默认授予)。该usage权限并不能被revoke(回收)。
​
#收回权限(不包含赋权权限)
REVOKE ALL PRIVILEGES ON *.* FROM username;
#收回赋权权限
REVOKE GRANT OPTION ON *.* FROM username;
mysql8.0 [(none)]>revoke grant  option on *.*  from xiaoming@'%';
Query OK, 0 rows affected (0.00 sec)
​
mysql8.0 [(none)]>select grant_priv,user from mysql.user;
+------------+------------------+
| grant_priv | user             |
+------------+------------------+
| Y          | root             |
| N          | xiaohong         |
| N          | xiaoming         |
| N          | mysql.infoschema |
| N          | mysql.session    |
| N          | mysql.sys        |
+------------+------------------+
mysql8.0 [(none)]>revoke all on *.* from xiaoming;
#操作完后重新刷新权限
mysql8.0 [(none)]>flush privileges;
mysql8.0 [(none)]>revoke select on mysql.user from xiaohong;

第四章 MySQL之sql语句

有关数据表的DML操作

INSERT INTO

DELETE、TRUNCATE

UPDATE

SELECT

条件查询

查询排序

聚合函数

分组查询

4.1 INSERT语句

#在表里面插入数据:默认情况下,一次插入操作只插入一行
方式1:
INSERT [INTO] 表名 [(column [, column...])] VALUES(value [, value...]);
方式2:
insert [into] 表名 set 字段1=值1, 字段2=值2
#一次性插入多条记录:
INSERT [INTO] table [(column [, column...])] VALUES(value [, value...]),(value [, value...])    
​
注:
1、如果为每列都指定值,则表名后不需列出插入的列名
2、可以使用如下方式一次插入多行:insert into 表名[(列名,…)] select 语句   
3、如果需要插入其他特殊字符,应该采用\转义字符做前缀
示例:
mysql8.0 [chap04]>create table t1(
    -> id int primary key,
    -> name char(30) not null,
    -> birthday date
    -> );
mysql8.0 [chap04]>insert t1 values (1,'xiaoming',20000101);
mysql8.0 [chap04]>insert into t1 values (2,'xiaohong',20000102),(3,'xiaolan',20000103),(4,'xiaohei',20000104);
mysql8.0 [chap04]>insert into t1(id,name) values (5,'xiaolv'),(6,'xiaobai');
mysql8.0 [chap04]>insert into t1 set id=6,name='xiaozi';

4.2 REPLACE语句

replace语句的语法格式有三种语法格式。
​
语法格式1:replace [into] 表名 [(字段列表)] values (值列表)
​
语法格式2:
    replace [into] 目标表名[(字段列表1) select (字段列表2) from 源表 where 条件表达式
    
语法格式3:
    replace [into] 表名 set 字段1=值1, 字段2=值2

REPLACE与INSERT语句区别:

replace语句的功能与insert语句的功能基本相同,不同之处在于:使用replace语句向表插入新记录时,如果新记录的主键值或者唯一性约束的字段值与已有记录相同,则已有记录先被删除(注意:已有记录删除时也不能违背外键约束条件),然后再插入新记录。

使用replace的最大好处就是可以将delete和insert合二为一(效果相当于更新),形成一个原子操作,这样就无需将delete操作与insert操作置于事务中了

mysql8.0 [chap04]>replace t1 (id,name,birthday) values (8,'xiaoqing',20010101);
mysql8.0 [chap04]>replace t1 values(5,'xiaolv',20000105);
mysql8.0 [chap04]>select * from t1;
+----+----------+------------+
| id | name     | birthday   |
+----+----------+------------+
|  1 | xiaoming | 2000-01-01 |
|  2 | xiaohong | 2000-01-02 |
|  3 | xiaolan  | 2000-01-03 |
|  4 | xiaohei  | 2000-01-04 |
|  5 | xiaolv   | 2000-01-05 |
|  6 | xiaobai  | NULL       |
|  7 | xiaozi   | NULL       |
|  8 | xiaoqing | 2001-01-01 |
+----+----------+------------+
mysql8.0 [chap04]>replace t1(id,name,birthday) values (9,'zhouyi',20010102),(10,'zhouer',20010102);

4.3 UPDATE语句

UPDATE 表名
SET column = value [, column = value] 
[WHERE condition];

修改可以一次修改多行数据,修改的数据可用where子句限定,where子句里是一个条件表达式,只有符合该条件的行才会被修改。没有where子句意味着where字句的表达式值为true。也可以同时修改多列,多列的修改中间采用逗号(,)隔开。

mysql8.0 [chap04]>select * from t1;
+----+----------+------------+
| id | name     | birthday   |
+----+----------+------------+
|  1 | xiaoming | 2000-01-01 |
|  2 | xiaohong | 2000-01-02 |
|  3 | xiaolan  | 2000-01-03 |
|  4 | xiaohei  | 2000-01-04 |
|  5 | xiaolv   | 2000-01-05 |
|  6 | xiaobai  | NULL       |
|  7 | xiaozi   | NULL       |
|  8 | xiaoqing | 2001-01-01 |
|  9 | zhouyi   | 2001-01-02 |
| 10 | zhouer   | 2001-01-02 |
+----+----------+------------+
10 rows in set (0.00 sec)
​
mysql8.0 [chap04]>update t1 set birthday=20010101 where id=6;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

4.4 delete和TRUNCATE语句

DELETE FROM table_name [where 条件];
TRUNCATE TABLE table_name

DROP、TRUNCATE、DELETE的区别:

delete:删除数据,保留表结构,可以回滚,如果数据量大,很慢。

truncate: 删除所有数据,保留表结构,不可以回滚,一次全部删除所有数据,速度相对很快。

drop: 删除数据和表结构,删除速度最快。

mysql8.0 [chap04]>delete from t1 where id=7;
Query OK, 1 row affected (0.00 sec)
mysql8.0 [chap04]>create table t2 select * from t1;
mysql8.0 [chap04]>truncate table t2;

4.5 SELECT语句

1、简单的SELECT语句:

#简单的SELECT语句:
SELECT {*, column [alias],...}
FROM table;
​
说明:
select *表示所有列。
FROM 提供数据源(表名/视图名)
mysql8.0 [chap04]>select * from t1;
mysql8.0 [chap04]>select id,name from t1;

2、SELECT语句中的算术表达式:

对数值型数据列、变量、常量可以使用算数操作符创建表达式(+ - * /) 对日期型数据列、变量、常量可以使用部分算数操作符创建表达式(+ -) 运算符不仅可以在列和常量之间进行运算,也可以在多列之间进行运算。

运算符的优先级: 乘法和除法的优先级高于加法和减法; 同级运算的顺序是从左到右; 表达式中使用括号可强行改变优先级的运算顺序;

mysql8.0 [chap04]>create table t3(
    -> id int primary key,
    -> name char(30) not null,
    -> salary int,
    -> performance decimal(3,2)
    -> );
mysql8.0 [chap04]>insert into t3 values(2,'xiaohong',8000,1.594),(2,'xiaohong',8000,1.594),(3,'xiaobai',9000,1.789);
mysql8.0 [chap04]>select * from t3;
+----+----------+--------+-------------+
| id | name     | salary | performance |
+----+----------+--------+-------------+
|  1 | xiaoming |  10000 |        1.34 |
|  2 | xiaohong |   8000 |        1.59 |
|  3 | xiaobai  |   9000 |        1.79 |
+----+----------+--------+-------------+
3 rows in set (0.00 sec)
​
mysql8.0 [chap04]>select id,name,salary*12,salary*performance from t3;
+----+----------+-----------+--------------------+
| id | name     | salary*12 | salary*performance |
+----+----------+-----------+--------------------+
|  1 | xiaoming |    120000 |           13400.00 |
|  2 | xiaohong |     96000 |           12720.00 |
|  3 | xiaobai  |    108000 |           16110.00 |
+----+----------+-----------+--------------------+
补充说明:MySQL的+默认只有一个功能:运算符
SELECT 100+80; # 结果为180
SELECT '123'+80; # 只要其中一个为数值,则试图将字符型转换成数值,转换成功做预算,结果为203
SELECT 'abc'+80; # 转换不成功,则字符型数值为0,结果为80
SELECT 'This'+'is'; # 转换不成功,结果为0
SELECT NULL+80; # 只要其中一个为NULL,则结果为NULL

NULL值的使用:

空值是指不可用、未分配的值
空值不等于零或空格
任意类型都可以支持空值
包括空值的任何算术表达式都等于空
字符串和null进行连接运算,得到也是null

补充说明:

安全等于运算符<=>
(1)可作为普通运算符的=,两个值进行比较时,2<=>2结果是1,2<=>3是0;
mysql8.0 [chap04]>select 2=2;
+-----+
| 2=2 |
+-----+
|   1 |
+-----+
1 row in set (0.00 sec)
​
mysql8.0 [chap04]>select 2<=>2;
+-------+
| 2<=>2 |
+-------+
|     1 |
+-------+
(2)也可以用于判断是否是NULL;where salary is NULL等价于where salary <=>NULL;where salary is not NULL等价于where not salary <=>null;
​
mysql8.0 [chap04]>insert t1(id,name) values(11,'zhousan');
mysql8.0 [chap04]>select * from t1 where birthday<=>null;
mysql8.0 [chap04]>select * from t1 where birthday is null;
+----+---------+----------+
| id | name    | birthday |
+----+---------+----------+
| 11 | zhousan | NULL     |
+----+---------+----------+
mysql8.0 [chap04]>select * from t1 where birthday is not null;
mysql8.0 [chap04]>select * from t1 where not birthday<=>null;

3、定义字段的别名:

改变列的标题头 用于表示计算结果的含义 作为列的别名 如果别名中使用特殊字符,或者是强制大小写敏感,或有空格时,都可以通过为别名添加加双引号实现。

mysql8.0 [chap04]>select name as "姓名",id,birthday "生日" from t1;
+----------+----+------------+
| 姓名     | id | 生日       |
+----------+----+------------+
| xiaoming |  1 | 2000-01-01 |
| xiaohong |  2 | 2000-01-02 |
| xiaolan  |  3 | 2000-01-03 |
| xiaohei  |  4 | 2000-01-04 |
| xiaolv   |  5 | 2000-01-05 |
| xiaobai  |  6 | 2001-01-01 |
| xiaoqing |  8 | 2001-01-01 |
| zhouyi   |  9 | 2001-01-02 |
| zhouer   | 10 | 2001-01-02 |
| zhousan  | 11 | NULL       |
+----------+----+------------+
mysql8.0 [chap04]>select id,name,salary*12 "年薪",salary*performance from t3;
+----+----------+--------+--------------------+
| id | name     | 年薪   | salary*performance |
+----+----------+--------+--------------------+
|  1 | xiaoming | 120000 |           13400.00 |
|  2 | xiaohong |  96000 |           12720.00 |
|  3 | xiaobai  | 108000 |           16110.00 |
+----+----------+--------+--------------------+
​

4、重复记录处理

#缺省情况下查询显示所有行,包括重复行
mysql8.0 [chap04]>select birthday from t1;
#使用DISTINCT关键字可从查询结果中清除重复行
mysql8.0 [chap04]>select distinct birthday from t1;    
#DISTINCT的作用范围是后面所有字段的组合
mysql8.0 [chap04]>select distinct name,birthday from t1;

5、使用where子句限制所选择的记录:

#使用WHERE子句限定返回的记录,WHERE子句在FROM 子句后。
语法:SELECT [DISTINCT] {*, column [alias], ...} FROM table [WHERE condition(s)] [order by column [alias], ...];   
WHERE中的字符串和日期值:字符串和日期要用单引号扩起来;日期值是格式敏感的。
​
#WHERE中比较运算符【>,>=,<,<=,=,!=】。
mysql8.0 [chap04]>select * from t1 where birthday<='2000-01-01';
+----+----------+------------+
| id | name     | birthday   |
+----+----------+------------+
|  1 | xiaoming | 2000-01-01 |
+----+----------+------------+
1 row in set (0.00 sec)
​
mysql8.0 [chap04]>select * from t1 where id<='3';
​
#使用IS NULL运算符,查询包含空值的记录
mysql8.0 [chap04]>select * from t1 where birthday is null;  
#where中between比较运算符,使用BETWEEN运算符显示某一值域范围的记录。
    SELECTlast_name, salary
    FROM employees
    WHERE salary BETWEEN 1000 AND 1500; 
mysql8.0 [chap04]>select * from t1 where birthday between'2000-01-01' and '2000=01-04';
​
#where中使用IN运算符,使用IN运算符获得匹配列表值的记录。
mysql8.0 [chap04]>select * from t1 where birthday in ('20000101','20000102','20010101')
​
    
#where中使用LIKE运算符,使用LIKE运算符执行模糊查询,查询条件可包含文字字符或数字,‘%’可表示零或多个字符,‘_’表示任意单字符。
mysql8.0 [chap04]>select * from t1 where name like 'xiao%';
    
​
#where中使用逻辑运算符
(1)使用and运算符,所有条件都是满足
  mysql8.0 [chap04]>select * from t1 where id>=2 and  birthday='20010101';  
(2)使用OR运算符,只要两个条件满足一个就可以
 mysql8.0 [chap04]>select * from t1 where id>=2 or  birthday='20010101'; 
(3)使用NOT运算符,取反的意思
mysql8.0 [chap04]>select * from t1 where id not in (1,3,5,7,9);
​
#联合查询,对两个结果求并集,使用union(去掉重复的)或者union all(不去掉重复的行)
mysql8.0 [chap04]>select * from employee where dept_id in (1,4) union select * from employee where dept_name in ('sale','tech') ;
mysql8.0 [chap04]>select * from employee where dept_id in (1,4) union all select * from employee where dept_name in ('sale','tech') ;
mysql8.0 [chap04]>select * from employee where dept_id in (1,4) or  dept_name in ('sale','tech') ;
​
#排序显示,查询语句执行的查询结果默认是按数据插入顺序排列,实际上可能需要按某列的值大小排列,按某列排序采用order by 列名[desc],列名…;设定排序列的时候可采用列名、列别名。
mysql8.0 [chap04]>select * from t1 order by birthday desc;
​
#where中使用正则表达式,<列名> regexp '正则表达式'
mysql8.0 [chap04]>select * from t1 where name regexp '^xiao'; 
​
基本正则:^,$,\,.,*,[0-9],[a-z],[A-Z],[a-Z],[^],\(\),\<,\>
扩展正则:+,?,(|)

4.6 SQL函数

聚合函数

聚合函数对一组值进行运算,并返回单个值。也叫分组函数。

COUNT(*|列名) 统计行数,*表示所有记录都不忽略,指定列名时会忽略null
AVG(数值类型列名) 平均值,忽略null
SUM (数值类型列名) 求和,忽略null
MAX(列名) 最大值,忽略null
MIN(列名) 最小值,忽略null
mysql8.0 [chap04]>create table employee(
    -> employ_id int,
    -> dept_id int,
    -> dept_name char(10),
    -> salary int
    -> );
mysql8.0 [chap04]>insert into employee set employ_id=100,dept_id=1,dept_name='boss';
mysql8.0 [chap04]>insert into employee values (101,2,'sale',10000),(102,2,'sale',9000),(103,4,'tech',12000),(104,2,'sale',5000),(105,3,'hr',8000),(106,4,'tech',10000);
mysql8.0 [chap04]>select count(*) from employee;
mysql8.0 [chap04]>select count(salary) from employee;
mysql8.0 [chap04]>select avg(salary) from employee;
mysql8.0 [chap04]>select sum(salary) from employee;
mysql8.0 [chap04]>select max(salary) from employee;

数据分组——GROUP BY

GROUP BY子句的真正作用在于与各种聚合函数配合使用。它用来对查询出来的数据进行分组。

分组的含义是:把该列具有相同值的多条记录当成一组记录处理,最后只输出一条记录。

#数据分组--GROUP BY
语法:SELECT column,group_function FROM table [WHERE condition] [GROUP BY group_by_expression] 
#每个部门的平均工资
mysql8.0 [chap04]>select dept_name,avg(salary) from employee group by dept_name; 
#如果select语句中的列未使用聚合函数,那么它必须出现在GROUP BY子句中
mysql8.0 [chap04]>select dept_id,dept_name,avg(salary) from employee group by dept_id,dept_name;
#出现在group by子句的字段可以不出现在select的列表当中
mysql8.0 [chap04]>select dept_name,avg(salary) from employee group by dept_id,dept_name;
#查每个部门的整体工资情况
mysql8.0 [chap04]>select dept_id,dept_name,avg(salary),max(salary),min(salary),sum(salary),count(*) from employee group by dept_id,dept_name;
​
#限定组的结果:HAVING子句,HAVING子句用来对分组后的结果再进行条件过滤。
语法:SELECT column, group_function FROM table [WHERE condition] [GROUP BY group_by_expression] [HAVING group_condition] [ORDER BYcolumn];
#查询部门平均工资大于10000的
mysql8.0 [chap04]>select dept_name,avg(salary) from employee group by dept_name having avg(salary)>10000;
#HAVING与WHERE的区别:WHERE是在分组前进行条件过滤, HAVING子句是在分组后进行条件过滤,WHERE子句中不能使用聚合函数,HAVING子句可以使用聚合函数。
mysql8.0 [chap04]>select dept_name,dept_id,avg(salary) from employee where dept_id > 1 group by dept_name,dept_id;
​
#对结果集排序:查询语句执行的查询结果默认是按数据插入顺序排列,实际上可能需要按某列的值大小排列,按某列排序采用order by 列名[desc],列名…;设定排序列的时候可采用列名、列别名。
mysql8.0 [chap04]>select dept_name,dept_id,avg(salary) from employee group by dept_name,dept_id order by dept_id,avg(salary);
​
#MySQL多行数据合并:GROUP_CONCAT
mysql8.0 [chap04]>select dept_id,dept_name,group_concat(employ_id) from employee group by dept_id,dept_name;
注意:使用 GROUP_CONCAT()函数必须对源数据进行分组,否则所有数据会被合并成一行
mysql8.0 [chap04]>select group_concat(employ_id) from employee;
+-----------------------------+
| group_concat(employ_id)     |
+-----------------------------+
| 100,101,102,103,104,105,106 |
+-----------------------------+
​
#查询结果限定,在SELECT语句最后可以用LIMLT来限定查询结果返回的起始记录和总数量。MySQL特有。
语法:SELECT … LIMIT offset_start,row_count;
offset_start:第一个返回记录行的偏移量。默认为0。
row_count:要返回记录行的最大数目。
#显示三行数据
mysql8.0 [chap04]>select * from employee limit 3;
#显示3-7行数据,共5行数据
mysql8.0 [chap04]>select  * from employee limit 2,5;

数值型函数

函数名称作用
ABS求绝对值
SQRT求平方根
POW 和 POWER两个函数的功能相同,返回参数的幂次方
MOD求余数
CEIL 和 CEILING两个函数功能相同,都是返回不小于参数的最小整数,即向上取整
FLOOR向下取整,返回值转化为一个BIGINT
RAND生成一个0~1之间的随机数,传入整数参数时,用来产生重复序列
ROUND对所传参数进行四舍五入
SIGN返回参数的符号

字符串函数

函数名称作用
LENGTH计算字符串长度函数,返回字符串的字节长度
CHAR_LENGTH计算字符串长度函数,返回字符串的字符长度,注意两者的区别
CONCAT合并字符串函数,返回结果为连接参数产生的字符串,参数可以是一个或多个
INSERT(str,pos,len,newstr)替换字符串函数
LOWER将字符串中的字母转换为小写
UPPER将字符串中的字母转换为大写
LEFT(str,len)从左侧字截取符串,返回字符串左边的若干个字符
RIGHT从右侧字截取符串,返回字符串右边的若干个字符
TRIM删除字符串左右两侧的空格
REPLACE(s,s1,s2)字符串替换函数,返回替换后的新字符串
SUBSTRING(s,n,len)截取字符串,返回从指定位置开始的指定长度的字符换
REVERSE字符串反转(逆序)函数,返回与原始字符串顺序相反的字符串
STRCMP(expr1,expr2)比较两个表达式的顺序。若expr1 小于 expr2 ,则返回 -1,0相等,1则相反
LOCATE(substr,str [,pos])返回第一次出现子串的位置
INSTR(str,substr)返回第一次出现子串的位置

日期和时间函数

函数名称作用
CURDATE() CURRENT_DATE() CURRENT_DATE两个函数作用相同,返回当前系统的日期值
CURTIME CURRENT_TIME() CURRENT_TIME两个函数作用相同,返回当前系统的时间值
NOW()返回当前系统的日期和时间值
SYSDATE返回当前系统的日期和时间值
DATE获取指定日期时间的日期部分
TIME获取指定日期时间的时间部分
MONTH获取指定日期中的月份
MONTHNAME获取指定曰期对应的月份的英文名称
DAYNAME获取指定曰期对应的星期几的英文名称
YEAR获取年份,返回值范围是 1970〜2069
DAYOFWEEK获取指定日期对应的一周的索引位置值,也就是星期数,注意周日是开始日,为1
WEEK获取指定日期是一年中的第几周,返回值的范围是否为 0〜52 或 1 〜53
DAYOFYEAR获取指定曰期是一年中的第几天,返回值范围是1~366
DAYOFMONTH 和 DAY两个函数作用相同,获取指定日期是一个月中是第几天,返回值范围是1~31
DATEDIFF(expr1,expr2)返回两个日期之间的相差天数,如 SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');
SEC_TO_TIME将秒数转换为时间,与TIME_TO_SEC 互为反函数
TIME_TO_SEC将时间参数转换为秒数,是指将传入的时间转换成距离当天00:00:00的秒数,00:00:00为基数,等于 0 秒

流程控制函数

函数名称作用
IF(expr,v1,v2)判断,流程控制,当expr = true时,或者为1时返回 v1,当expr = false、null 、0时返回v2
IFNULL(v1,v2)判断是否为空,如果 v1 不为 NULL,则 IFNULL 函数返回 v1,否则返回 v2
CASE搜索语句

流程控制函数示例:

(1)使用IF()函数进行条件判断
mysql>SELECT IF(12,2,3),
 ->    IF(1<2,'yes ','no'),
 ->    IF(STRCMP('test','test1'),'no','yes');
+------------+---------------------+---------------------------------------+
| IF(12,2,3) | IF(1<2,'yes ','no') | IF(STRCMP('test','test1'),'no','yes') |
+------------+---------------------+---------------------------------------+
|      2 | yes         | no                  |
+------------+---------------------+---------------------------------------+
1 row in set (0.00 sec)
​
(2)分别显示emp表有奖金和没奖金的员工信息。
mysql> select ename,comm,if(comm is null,'没奖金,呵呵','有奖金,嘻嘻') 备注 from emp;
+-----------+-------+------------------+
| ename   | comm | 备注       |
+-----------+-------+------------------+
| 甘宁   |  NULL | 没奖金,呵呵   |
| 黛绮丝  |  3000 | 有奖金,嘻嘻   |
| 殷天正  |  5000 | 有奖金,嘻嘻   |
| 刘备   |  NULL | 没奖金,呵呵   |
| 谢逊   | 14000 | 有奖金,嘻嘻   |
| 关羽   |  NULL | 没奖金,呵呵   |
| 张飞   |  NULL | 没奖金,呵呵   |
| 诸葛亮  |  NULL | 没奖金,呵呵   |
| 曾阿牛  |  NULL | 没奖金,呵呵   |
| 韦一笑  |   0 | 有奖金,嘻嘻   |
| 周泰   |  NULL | 没奖金,呵呵   |
| 程普   |  NULL | 没奖金,呵呵   |
| 庞统   |  NULL | 没奖金,呵呵   |
| 黄盖   |  NULL | 没奖金,呵呵   |
| 张三   | 50000 | 有奖金,嘻嘻   |
+-----------+-------+------------------+
15 rows in set (0.00 sec)
​
(3)使用IFNULL()函数进行条件判断
IFNULL() 函数语法格式为:IFNULL(expression, alt_value)
mysql>  SELECT IFNULL(1,2), IFNULL(NULL,10), IFNULL(1/0, 'wrong');
+-------------+-----------------+----------------------+
| IFNULL(1,2) | IFNULL(NULL,10) | IFNULL(1/0, 'wrong') |
+-------------+-----------------+----------------------+
|      1 |        10 | wrong        |
+-------------+-----------------+----------------------+
1 row in set, 1 warning (0.00 sec)
#IFNULL() 函数用于判断第一个表达式是否为 NULL,如果为 NULL 则返回第二个参数的值,如果不为NULL 则返回第一个参数的值。
​
(4)使用CASE value WHEN语句执行分支操作
语法:CASE  <表达式>
   WHEN <值1> THEN <操作>
   WHEN <值2> THEN <操作>
   ...
   ELSE <操作>
END
将 <表达式> 的值逐一和每个 when 的 <值> 进行比较,如果跟某个<值>相等,则执行它后面的 <操作> ,如果所有 when 的值都不匹配,则执行 else 的操作,如果 when 的值都不匹配,且没写 else,则会报错。
​
mysql> SELECT CASE 2 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END;
+------------------------------------------------------------+
| CASE 2 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END |
+------------------------------------------------------------+
| two                            |
+------------------------------------------------------------+
1 row in set (0.00 sec)
​
mysql8.0 [chap04]>select dept_name,dept_id,case dept_id when 1 then 'boss' when 2 then 'sale'  else 'other'
end as 'bumen' from employee;
+-----------+---------+-------+
| dept_name | dept_id | bumen |
+-----------+---------+-------+
| boss      |       1 | boss  |
| sale      |       2 | sale  |
| sale      |       2 | sale  |
| tech      |       4 | other |
| sale      |       2 | sale  |
| hr        |       3 | other |
| tech      |       4 | other |
+-----------+---------+-------+
mysql8.0 [chap04]>select employ_id,dept_id,dept_name,salary,case dept_name when 'sale' then salary*1.3 when
'tech' then salary*1.1 else salary end as last_salary from employee;
​
​
(5)使用CASE WHEN语句执行分支操作
mysql> SELECT CASE WHEN 1<0 THEN 'true' ELSE 'false' END;
+--------------------------------------------+
| CASE WHEN 1<0 THEN 'true' ELSE 'false' END |
+--------------------------------------------+
| false                   |
+--------------------------------------------+
1 row in set (0.00 sec)
​
mysql8.0.30 [chap04]>select name,salary,case  when salary<=300 then '[0,300]' when salary<=500 then '(300,500]' when salary<=1000 then '(500,1000]' when salary is null then 'dont know' else '(1000,*)' end
 'salary level' from employee;

4.7 多表关联查询

1. inner join:内连接,只取得键值一致的部分,代表选择的是两个表键值交叉的部分。
语法如下:
SELECT 列名1,列名2... FROM 表1 INNER JOIN 表2 ON 表1.列=表2.列 [and 条件表达式 ][ WhERE 条件语句 ] [ order by 列 [desc] ];
mysql8.0 [chap04]>create table dept( dept_id int, dept_name char(10) );
mysql8.0 [chap04]>insert into dept values (1,'boss'),(2,'sale'),(3,'hr'),(4,'tech'),(5,'finance');
mysql8.0 [chap04]>alter table employee add foreign key(dept_id) references dept(dept_id);
mysql8.0 [chap04]>insert into employee set employ_id=107;
mysql8.0 [chap04]>select * from employee inner join dept on employee.dept_id=dept.dept_id where
dept.dept_name='sale';
mysql8.0 [chap04]>select * from employee inner join dept on employee.dept_id=dept.dept_id and salary>8000;
mysql8.0 [chap04]>select * from employee inner join dept on employee.dept_id=dept.dept_id and salary>8000 order by salary;
​
2. left join:左连接,代表选择的是前面一个表的全部。左连接是以左表为标准,只查询在左边表中存在的数据。语法如下:
SELECT 列名1 FROM 表1 LEFT OUTER JOIN 表2 ON 表1.列=表2.列 WhERE 条件语句;
mysql8.0 [chap04]>select e.employ_id,e.dept_id,e.salary,d.dept_name from employee e left outer join dept d on e.dept_name=d.dept_name;
​
3. right join:右连接,代表选择的是后面一个表的全部。右连接将会以右边作为基准,进行检索。语法如下:
SELECT 列名1 FROM 表1 RIGHT OUTER JOIN 表2 ON 表1.列=表2.列 WhERE 条件语句;
#列出所有部门的员工,包括没有员工的部门
mysql8.0 [chap04]>select  d.dept_id,d.dept_name,e.employ_id,e.salary from employee e right join
dept d on e.dept_id=d.dept_id;
​
​
4.自连接,自连接顾名思义就是自己跟自己连接,参与连接的表都是同一张表。(通过给表取别名虚拟出)
#查找比自己mgr岁数大的员工和mgr的姓名和年龄
mysql8.0 [chap04]>create table t4(
    -> name char(20),
    -> age int,
    -> mgr char(20)
    -> );
mysql8.0 [chap04]>insert into  t4 values ('xiaoming',29,'xiao'),('xiaohong',26,'xiao'),('zhouyi',19,'zhou'),('xiao',28,'boss'),('zhou',30,'boss');
mysql8.0 [chap04]>select e.name,e.age,m.name,m.age from t4 e join t4 m on e.mgr=m.name and  e.age > m.age;
mysql8.0 [chap04]>select e.name,e.age,m.name,m.age from t4 e,t4 m where e.mgr=m.name and  e.age >
 m.age;
​
5.交叉连接:不适用任何匹配条件。生成笛卡尔积
mysql8.0 [chap04]>select * from dept,t4;

子查询,子查询是将一个查询语句嵌套在另一个查询语句中。内部嵌套其他select语句的查询,称为外查询或主查询。
注意:
1、子查询要包含在括号内。
2、将子查询放在比较条件的右侧。
3、单行操作符对应单行子查询,多行操作符对应多行子查询
​
#查询工资最低的员工的信息
mysql8.0 [chap04]>select * from employee e where e.salary=(select min(salary) from employee);
​
#查询出高于hr部门平均工资的员工
mysql8.0 [chap04]>select * from employee e where e.salary>(select avg(salary) from employee where dept_name='hr');
 
#查询出比sale部门所有员工工资高的员工信息
mysql8.0 [chap04]>select * from employee where salary >(select max(salary) from employee where dept_name='sale') and dept_name!='sale';
mysql8.0 [chap04]>select * from employee where salary>all(select salary from employee where dept_name='sale') and dept_name!='sale';
​
#查询出比sale部门任意一个员工工资高的员工信息,只要比其中随便一个工资高都可以
mysql8.0 [chap04]>select * from employee where salary>any(select salary from employee where dept_name='sale') and dept_name!='sale';
​
​
# 获取员工的名字和部门的名字 select后面接子查询
mysql8.0 [chap04]>alter table employee drop dept_name;
mysql8.0 [chap04]>select employ_id,(select dept_name from dept d where d.dept_id=e.dept_id) dept_name from employee e;
mysql8.0 [chap04]>select employ_id,d.dept_name from employee e left join dept d on e.dept_id=d.dept_id;
# 查询所有管理层的信息
mysql8.0 [chap04]>select * from t4 e,(select distinct mgr from t4) m where e.name=m.mgr;

第三次作业

一、单表查询
素材: 表名:worker-- 表中字段均为中文,比如 部门号 工资 职工号 参加工作 等
CREATE TABLE `worker` (
 `部门号` int(11) NOT NULL,
 `职工号` int(11) NOT NULL,
 `工作时间` date NOT NULL,
 `工资` float(8,2) NOT NULL,
 `政治面貌` varchar(10) NOT NULL DEFAULT '群众',
 `姓名` varchar(20) NOT NULL,
 `出生日期` date NOT NULL,
 PRIMARY KEY (`职工号`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
INSERT INTO `worker` (`部门号`, `职工号`, `工作时间`, `工资`, `政治面貌`, `姓名`, `出生日期`) VALUES (101, 1001, '2015-5-4', 3500.00, '群众', '张三', '1990-7-1');
INSERT INTO `worker` (`部门号`, `职工号`, `工作时间`, `工资`, `政治面貌`, `姓名`, `出生日期`) VALUES (101, 1002, '2017-2-6', 3200.00, '团员', '李四', '1997-2-8');
INSERT INTO `worker` (`部门号`, `职工号`, `工作时间`, `工资`, `政治面貌`, `姓名`, `出生日期`) VALUES (102, 1003, '2011-1-4', 8500.00, '党员', '王亮', '1983-6-8');
INSERT INTO `worker` (`部门号`, `职工号`, `工作时间`, `工资`, `政治面貌`, `姓名`, `出生日期`) VALUES (102, 1004, '2016-10-10', 5500.00, '群众', '赵六', '1994-9-5');
INSERT INTO `worker` (`部门号`, `职工号`, `工作时间`, `工资`, `政治面貌`, `姓名`, `出生日期`) VALUES (102, 1005, '2014-4-1', 4800.00, '党员', '钱七', '1992-12-30');
INSERT INTO `worker` (`部门号`, `职工号`, `工作时间`, `工资`, `政治面貌`, `姓名`, `出生日期`) VALUES (102, 1006, '2017-5-5', 4500.00, '党员', '孙八', '1996-9-2');
​
1、显示所有职工的基本信息。   
2、查询所有职工所属部门的部门号,不显示重复的部门号。  
3、求出所有职工的人数。  
4、列出最高工资和最低工资。   
5、列出职工的平均工资和总工资。   
6、创建一个只有职工号、姓名和参加工作的新表,名为工作日期表。 
7、显示所有女职工的年龄。 
8、列出所有姓刘的职工的职工号、姓名和出生日期。
9、列出1960年以前出生的职工的姓名、参加工作日期。
10、列出工资在1000-2000之间的所有职工姓名。 
11、列出所有陈姓和李姓的职工姓名。
12、列出所有部门号为2和3的职工号、姓名、党员否。  
13、将职工表worker中的职工按出生的先后顺序排序。
14、显示工资最高的前3名职工的职工号和姓名。 
15、求出各部门党员的人数。 
16、统计各部门的工资和平均工资
17、列出总人数大于4的部门号和总人数。
​

1、显示所有职工的基本信息。   

select * from worker;

2、查询所有职工所属部门的部门号,不显示重复的部门号。  

select distinct 部门号 from worker ;

3、求出所有职工的人数。  

select count(*) 员工人数 from worker;

4、列出最高工和最低工资。

select max(工资),min(工资) from worker;
 
5、列出职工的平均工资和总工资。

select avg(工资) 平均工资,SUM(工资) 总工资 FROM worker;

6、创建一个只有职工号、姓名和参加工作的新表,名为工作日期表。 

CREATE TABLE `工作日期` (
 `职工号` INT(11)     NOT NULL,
 `姓名` VARCHAR(20)     NOT NULL,
`工作时间` DATE     NOT NULL,
PRIMARY KEY (`职工号`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

7、显示所有职工的年龄。 

SELECT 姓名,DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS(出生日期)), '%Y')+0 AS age FROM worker;

8、列出所有姓刘的职工的职工号、姓名和出生日期。

SELECT 职工号,姓名,出生日期 FROM worker WHERE 姓名 LIKE '刘%';

9、列出1960年以后出生的职工的姓名、参加工作日期。

SELECT 姓名,工作时间 FROM worker WHERE 出生日期>1960-01-01;

10、列出工资在4000-5000之间的所有职工姓名。 

SELECT 姓名 FROM worker WHERE 工资 BETWEEN 4000 AND 5000;

11、列出所有部门号为101和102的职工号、姓名、党员否。  

SELECT 职工号,姓名,政治面貌 FROM worker WHERE 部门号=101 or 部门号=102;

12、将职工表worker中的职工按出生的先后顺序排序。

SELECT * FROM worker ORDER BY 出生日期;

13、显示工资最高的前3名职工的职工号和姓名。 

SELECT 职工号,姓名 FROM worker ORDER BY 工资 DESC LIMIT 3;

14、求出各部门党员的人数。 

SELECT 部门号,COUNT(*) 党员人数 FROM worker WHERE 政治面貌='党员' GROUP BY 部门号;

15、统计各部门的工资和平均工资

SELECT 工资,AVG(工资) 平均工资 FROM worker GROUP BY 部门号;

16、列出总人数大于3的部门号和总人数。

SELECT 部门号,COUNT(*) 总人数 FROM worker GROUP BY 部门号 HAVING 总人数>3;



二、多表查询
1.创建student和score表
CREATE  TABLE student (
id  INT(10)  NOT NULL  UNIQUE  PRIMARY KEY ,
name  VARCHAR(20)  NOT NULL ,
sex  VARCHAR(4) ,
birth  YEAR,
department  VARCHAR(20) ,
address  VARCHAR(50)
);
创建score表。SQL代码如下:
CREATE  TABLE score (
id  INT(10)  NOT NULL  UNIQUE  PRIMARY KEY  AUTO_INCREMENT ,
stu_id  INT(10)  NOT NULL ,
c_name  VARCHAR(20) ,
grade  INT(10)
);
2.为student表和score表增加记录
向student表插入记录的INSERT语句如下:
INSERT INTO student VALUES( 901,'张老大', '男',1985,'计算机系', '北京市海淀区');
INSERT INTO student VALUES( 902,'张老二', '男',1986,'中文系', '北京市昌平区');
INSERT INTO student VALUES( 903,'张三', '女',1990,'中文系', '湖南省永州市');
INSERT INTO student VALUES( 904,'李四', '男',1990,'英语系', '辽宁省阜新市');
INSERT INTO student VALUES( 905,'王五', '女',1991,'英语系', '福建省厦门市');
INSERT INTO student VALUES( 906,'王六', '男',1988,'计算机系', '湖南省衡阳市');
向score表插入记录的INSERT语句如下:
INSERT INTO score VALUES(NULL,901, '计算机',98);
INSERT INTO score VALUES(NULL,901, '英语', 80);
INSERT INTO score VALUES(NULL,902, '计算机',65);
INSERT INTO score VALUES(NULL,902, '中文',88);
INSERT INTO score VALUES(NULL,903, '中文',95);
INSERT INTO score VALUES(NULL,904, '计算机',70);
INSERT INTO score VALUES(NULL,904, '英语',92);
INSERT INTO score VALUES(NULL,905, '英语',94);
INSERT INTO score VALUES(NULL,906, '计算机',90);
INSERT INTO score VALUES(NULL,906, '英语',85);
​
1.查询student表的所有记录
2.查询student表的第2条到4条记录
3.从student表查询所有学生的学号(id)、姓名(name)和院系(department)的信息
4.从student表中查询计算机系和英语系的学生的信息
5.从student表中查询年龄18~22岁的学生信息
6.从student表中查询每个院系有多少人
7.从score表中查询每个科目的最高分
8.查询李四的考试科目(c_name)和考试成绩(grade)
9.用连接的方式查询所有学生的信息和考试信息
10.计算每个学生的总成绩
11.计算每个考试科目的平均成绩
12.查询计算机成绩低于95的学生信息
13.查询同时参加计算机和英语考试的学生的信息
14.将计算机考试成绩按从高到低进行排序
15.从student表和score表中查询出学生的学号,然后合并查询结果
16.查询姓张或者姓王的同学的姓名、院系和考试科目及成绩
17.查询都是湖南的学生的姓名、年龄、院系和考试科目及成绩

1.查询student表的所有记录

SELECT * FROM student;

2.查询student表的第2条到4条记录

SELECT * FROM student LIMIT 1,3;

3.从student表查询所有学生的学号(id)、姓名(name)和院系(department)的信息

SELECT id 学号,name 姓名,department 院系 FROM student;

4.从student表中查询计算机系和英语系的学生的信息

SELECT * FROM student WHERE department='计算机系' or department='英语系';

5.从student表中查询年龄18~22岁的学生信息

SELECT  * FROM student where birth>2000 and  birth<2002;

6.从student表中查询每个院系有多少人

SELECT department,count(*) 人数 from student group by department;

7从score表中查询每个科目的最高分

SELECT c_name,max(grade) from score group by c_name;

8.查询李四的考试科目(c_name)和考试成绩(grade)

select c.c_name,c.grade from student s inner join score c on s.id=c.stu_id where s.name='李四';

9.用连接的方式查询所有学生的信息和考试信息

select * from student inner join score on student.id=score.stu_id;

10.计算每个学生的总成绩

select stu_id,sum(grade) 总成绩 from score group by stu_id;

11.计算每个考试科目的平均成绩

select c_name,avg(grade) 平均成绩 from score group by c_name;

12.查询计算机成绩低于95的学生信息

select  s.* from student s inner join score c on s.id=c.stu_id WHERE grade<95 and c_name='计算机';

13.查询同时参加计算机和英语考试的学生的信息

select s.* from student s inner join score c on s.id=c.stu_id where c_name='计算机' and c_name='英语';

14.将计算机考试成绩按从高到低进行排序

select grade from score where c_name='计算机' order by grade desc;

15.从student表和score表中查询出学生的学号,然后合并查询结果

select s.name,c.stu_id from student s inner join score c on s.id=c.stu_id;

16.查询姓张或者姓王的同学的姓名、院系和考试科目及成绩

select name,department,c_name,grade from student s  inner join score c  on s.id=c.stu_id where  s.name like '张%' or name like '王%';

17.查询都是湖南的学生的姓名、年龄、院系和考试科目及成绩

select name,department,c_name,grade from student s inner join score c on s.id=c.stu_id where address like '湖南%';
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/344916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【图解数据结构与算法】数据结构与算法知识点整理 Data Structures and Algorithms

程序数据结构算法 数据结构是可以存储和组织数据的命名位置。 算法是用于解决特定问题的一组步骤。 数据结构是指&#xff1a;一种数据组织、管理和存储的格式&#xff0c;它可以帮助我们实现对数据高效的访问和修改。 数据结构 数据元素 元素之间的结构。 如果说数据结…

什么人合适学习Python

发了几天的Python基础&#xff0c;也认识了一些朋友&#xff0c;忽然有人问起&#xff0c;说为啥学Python&#xff0c;或者说啥人学习Python&#xff0c;作为一个教龄8年从Python一线讲师到Python教学主管的我和大家分享一下个人的看法&#xff0c;还是提前说一下&#xff0c;个…

winapi模拟鼠标按住左键拖动

继前文《windows下通过uiAutomation技术获取ui元素》介绍获取ui元素信息后&#xff0c;还需要对信息进行修改&#xff0c;但是 uiAutomation 技术并未提供可修改的 api&#xff0c;只能另辟他径看看了。 以 camera raw 为例&#xff0c;已知的是可将鼠标放在指定区域位置&#…

电力国家(行业)标准目录

1、3&#xff5e;63kV交流高压负荷开关 GB 3804-90 代替 GB 3804-882、电气装置安装工程35kV及以下架空电力线路施工及验收规范Code for construction and acceptance of 35kVand umder over head power levels electricequipment installation engineeringGB50173—923、带电作…

论文文献引用规范和标准(国标GBT7714)@endnote国标样式@citation交叉引用编号

文章目录论文文献引用规范和标准&#xff08;国标GBT7714&#xff09;国标GBT7714-2015endnote stylerefs简述国标GBT7714条目的组织格式&#x1f388;Noteword中的文献交叉引用超链接[编号]&#x1f388;正则高级搜索批量选中引用序号上标调整更新引用编号项段落内容对齐居中&…

python爬虫学习记录

初识爬虫 爬虫的概念 「什么是爬虫」 爬虫&#xff1a;通过编写程序&#xff0c;模拟浏览器上网&#xff0c;并抓取有价值的数据的过程 反爬虫&#xff1a;门户网站通过制定相应的策略或技术手段&#xff0c;来阻止爬虫程序对其网站数据的爬取 反反爬&#xff1a;爬虫程序…

操作系统(五)页面置换算法与分配策略

操作系统&#xff08;五&#xff09;页面置换算法与分配策略 一、页面置换算法 1、最佳置换算法&#xff08;OPT&#xff09; 每次选择淘汰的页面将是以后永不使用&#xff0c;或者在最长时间内不再被访问的页面&#xff0c;这样可以保证最低的缺页率 实际上就是从当前内存块…

【Kubernetes】【一】Kubernetes介绍

Kubernetes介绍 应用部署方式演变 在部署应用程序的方式上&#xff0c;主要经历了三个时代&#xff1a; 传统部署&#xff1a;互联网早期&#xff0c;会直接将应用程序部署在物理机上 优点&#xff1a;简单&#xff0c;不需要其它技术的参与 缺点&#xff1a;不能为应用程序定…

PDF SDK for Linux 8.4.2 Crack

PDF SDK for Linux 是适用于任何 Linux 企业或云应用程序的强大解决方案&#xff0c;非常适合需要完全可定制的 PDF 查看器或后端流程的任何 Linux 开发人员。 将 Foxit PDF SDK 嵌入到基于 Linux 的应用程序中非常容易。只需打开您最喜欢的 Linux IDE&#xff0c;复制您需要的…

电容笔和Apple pencil的区别有啥?学生党电容笔推荐

普通的电容笔与 Apple Pencil最大的区别在于&#xff0c;普通的电容笔没有像苹果电容笔那样的重力压感&#xff0c;而仅仅只有一个倾斜的压敢。但平替电容笔的其他性能也很不错&#xff0c;几乎和苹果 Pencil一样&#xff0c;而且平替电容笔的售价只需200元左右。目前&#xff…

react+antd+Table里切换Switch改变状态onChange 传参

场景&#xff1a;table列表里面&#xff0c;操作用Switch切换状态。对应列改变操作在colums里面// 表格行const colums: ColumnsType<potentialType> [{title: useLocale(创建时间),dataIndex: creation_date,key: creation_date,align: center,render: (v: string, rec…

【Python安全编程】Python实现网络主机和端口扫描

文章目录前言环境准备Python实现主机扫描基于ARP协议基于ICMP协议普通版本多线程版本Python实现端口扫描扫描单个端口利用多线程扫描端口后记前言 本文主要讲几个利用Python实现网络扫描的小例子&#xff0c;可以结合多线程或多进程编程改进实例 我曾经走过多遥远的路 跨越过多…

windows环境下安装Nginx及常用操作命令

windows环境下安装Nginx及常用操作命令nginx基本概述基本用途nginx安装nginx基本概述 Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器。基本用途 nginx是一个轻量级高并发服务器&#xff0c;而tomcat并不是。nginx一般被用来做反向代理&#xff0c;将请求转发到应用…

The Social-Engineer Toolkit(社会工程学工具包)互联网第一篇全模块讲解

一、工具介绍 Social-Engineer Toolkit 是一个专为社会工程设计的开源渗透测试框架&#xff0c;可以帮助或辅助你完成二维码攻击、可插拔介质攻击、鱼叉攻击和水坑攻击等。SET 本身提供了大量攻击选项&#xff0c;可让您快速进行信任型攻击&#xff0c;也是一款高度自定义工具…

Fluent Python 笔记 第 14 章 可迭代的对象、迭代器和生成器

迭代是数据处理的基石。扫描内存中放不下的数据集时&#xff0c;我们要找到一种惰性获取数据项的方式&#xff0c;即按需一次获取一个数据项。这就是迭代器模式(Iterator pattern)。本章说明 Python 语言是如何内置迭代器模式的&#xff0c;这样就避免了自己手动去实现。 在 P…

Mask-RCNN(3) : 自定义数据集读取(VOC COCO)以及pycocotools的使用

文章目录1. COCO数据读取1.1 COCO数据集目录结构1.2 pycocotools的使用1.3 COCODetection类__init__方法__getitem__方法2. VOC数据读取2.1 VOC数据集目录结构2.2 VOCInstances类__init__方法2.3 __getitem__方法参考1. COCO数据读取 1.1 COCO数据集目录结构 下载并解压COCO数…

MySQL 6:MySQL存储过程、存储函数

MySQL 5.0 版本开始支持存储过程。存储过程是一组SQL语句&#xff0c;功能强大&#xff0c;可以实现一些复杂的逻辑功能&#xff0c;类似于JAVA语言中的方法&#xff1b;存储是数据库SQL语言层面的代码封装和复用。 存储过程有输入输出参数&#xff0c;可以声明变量&#xff0…

Android Monkey

1、Monkey&#xff08;Monkey是发送伪随机用户事件的工具&#xff09;介绍&#xff1a; Monkey测试是Android平台自动化测试的一种手段&#xff0c;通过Monkey程序模拟用户触摸屏幕、滑动Trackball、按键等操作来对设备上的程序进行压力测试&#xff0c;检测程序多久的时间会发…

安灯(andon)系统是车间现场管理的必备工具

安灯&#xff08;andon&#xff09;系统应用越来越广泛&#xff0c;不单单局限于汽车行业&#xff0c;更多生产型企业意识到了提高工作效率的重要性&#xff0c;提高工作效率根本的能提高生产水平&#xff0c;提高产量&#xff0c;而且安灯&#xff08;andon&#xff09;系统不…

python(16)--类

一、类的基本操作1.定义一个类格式&#xff1a;class Classname( )&#xff1a;内容&#x1f48e;鄙人目前还是一名学生&#xff0c;最熟悉的也就是学校了&#xff0c;所以就以学校为例子来建立一个类吧class School():headline"帝国理工大学"def schoolmotto(self):…