数据库概述及数据准备
SQL 概述
SQL,一般发音为sequel,SQL的全称Structured Query Language),SQL用来和数据库打交道,完成和数据库的通信,SQL是一套标准。但是每一个数据库都有自己的特性别的数据库没有,当使用这个数据库特性相关的功能,这时SQL语句可能就不是标准了.(90%以上的SQL都是通用的)
什么是数据库
数据库,通常是一个或一组文件,保存了一些符合特定规格的数据,数据库对应的英语单词是DataBase,简称:DB,数据库软件称为数据库管理系统(DBMS),全称为DataBase Management System,如:Oracle、SQL Server、MySql、Sybase、informix、DB2、interbase、PostgreSql 。
MySQL概述
MySQL最初是由“MySQL AB”公司开发的一套关系型数据库管理系统(RDBMS-Relational Database Mangerment System)。
MySQL不仅是最流行的开源数据库,而且是业界成长最快的数据库,每天有超过7万次的下载量,其应用范围从大型企业到专有的嵌入应用系统。
MySQL AB是由两个瑞典人和一个芬兰人:David Axmark、Allan Larsson和Michael “Monty” Widenius在瑞典创办的。
在2008年初,Sun Microsystems收购了MySQL AB公司。在2009年,Oracle收购了Sun公司,使MySQL并入Oracle的数据库产品线。
MySQL的部署
mysql的部署方式有两种,一是通过正常的安装方式,二是通过容器方式拉起。采用容器化方式进行部署安装,前提是环境中已经安装docker环境和docker-compose。
创建docker-compose.yml文件
version: '3'services:db:image: mysql:5.7.17restart: alwaysenvironment:MYSQL_ROOT_PASSWORD: 123456command:--default-authentication-plugin=mysql_native_password--character-set-server=utf8mb4--collation-server=utf8mb4_general_ci--explicit_defaults_for_timestamp=true--lower_case_table_names=1--max_allowed_packet=128M;ports:- 3306:3306volumes:- ./data:/var/lib/mysql
启动docker-compose脚本
docker-compose up -d
表
表(table)是一种结构化的文件,可以用来存储特定类型的数据,如:学生信息,课程信息,都可以放到表中。另外表都有特定的名称,而且不能重复。表中具有几个概念:列、行、主键。 列叫做字段(Column),行叫做表中的记录,每一个字段都有:字段名称/字段数据类型/字段约束/字段长度
创建表
在 MySQL 中,可以使用 CREATE TABLE 语句创建表。其语法格式为:
create table tableName(columnName dataType(lenght),.....columnName dataType(lenght));set character_set_results='gbk'
创建表的时候,表中有字段,每一个字段有:
* 字段名* 字段数据类型* 字段长度限制* 字段约束
MySql常用数据类型
| 类型 | 描述 |
|---|---|
| Char(长度) | 定长字符串,存储空间大小固定,适合作为主键或外键 |
| Varchar(长度) | 变长字符串,存储空间等于实际数据空间 |
| double(有效数字位数,小数位) | 数值型 |
| Float(有效数字位数,小数位) | 数值型 |
| Int( 长度) | 整型 |
| bigint(长度) | 长整型 |
| Date | 日期型 年月日 |
| DateTime | 日期型 年月日 时分秒 毫秒 |
| time | 日期型 时分秒 |
| BLOB | Binary Large OBject(二进制大对象) |
| CLOB | Character Large OBject(字符大对象) |
| 其它………………… |
例子: 建立学生信息表,字段包括:学号、姓名、性别、出生日期、email、班级标识。
mysql> create table t_student(-> student_id int(10),-> student_name varchar(20),-> sex char(2),-> birthday date,-> email varchar(30),-> classes_id int(3)-> );Query OK, 0 rows affected (0.18 sec)mysql> desc t_student;+--------------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------------+-------------+------+-----+---------+-------+| student_id | int(10) | YES | | NULL | || student_name | varchar(20) | YES | | NULL | || sex | char(2) | YES | | NULL | || birthday | date | YES | | NULL | || email | varchar(30) | YES | | NULL | || classes_id | int(3) | YES | | NULL | |+--------------+-------------+------+-----+---------+-------+6 rows in set (0.22 sec)
增加/删除/修改表结构
采用alter table来增加/删除/修改表结构,不影响表中的数据。
添加字段
如:需求发生改变,需要向t_student中加入联系电话字段,字段名称为:contatct_tel 类型为varchar(40)。
mysql> alter table t_student add contact_tel varchar(40);Query OK, 0 rows affected (0.15 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> desc t_student;+--------------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------------+-------------+------+-----+---------+-------+| student_id | int(10) | YES | | NULL | || student_name | varchar(20) | YES | | NULL | || sex | char(2) | YES | | NULL | || birthday | date | YES | | NULL | || email | varchar(30) | YES | | NULL | || classes_id | int(3) | YES | | NULL | || contact_tel | varchar(40) | YES | | NULL | |+--------------+-------------+------+-----+---------+-------+7 rows in set (0.21 sec)
修改字段
如:student_name无法满足需求,长度需要更改为100。
mysql> alter table t_student modify student_name varchar(100);Query OK, 0 rows affected (0.10 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> desc t_student;+--------------+--------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------------+--------------+------+-----+---------+-------+| student_id | int(10) | YES | | NULL | || student_name | varchar(100) | YES | | NULL | || sex | char(2) | YES | | NULL | || birthday | date | YES | | NULL | || email | varchar(30) | YES | | NULL | || classes_id | int(3) | YES | | NULL | || contact_tel | varchar(40) | YES | | NULL | |+--------------+--------------+------+-----+---------+-------+7 rows in set (0.18 sec)
如sex字段名称感觉不好,想用gender那么就需要更爱列的名称
mysql> alter table t_student change sex gender char(2);Query OK, 0 rows affected (0.12 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> desc t_student;+--------------+--------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------------+--------------+------+-----+---------+-------+| student_id | int(10) | YES | | NULL | || student_name | varchar(100) | YES | | NULL | || gender | char(2) | YES | | NULL | || birthday | date | YES | | NULL | || email | varchar(30) | YES | | NULL | || classes_id | int(3) | YES | | NULL | || contact_tel | varchar(40) | YES | | NULL | |+--------------+--------------+------+-----+---------+-------+7 rows in set (0.19 sec)
删除字段
如:删除联系电话字段。
mysql> alter table t_student drop contact_tel;Query OK, 0 rows affected (0.09 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> desc t_student;+--------------+--------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------------+--------------+------+-----+---------+-------+| student_id | int(10) | YES | | NULL | || student_name | varchar(100) | YES | | NULL | || gender | char(2) | YES | | NULL | || birthday | date | YES | | NULL | || email | varchar(30) | YES | | NULL | || classes_id | int(3) | YES | | NULL | |+--------------+--------------+------+-----+---------+-------+6 rows in set (0.19 sec)
数据库增删改
添加、修改和删出都属于DML,主要包含的语句:insert、update、delete
增(insert)
INSERT VALUES 的语法格式为:
INSERT INTO <表名> [ <列名1> [ , … <列名n>] ]VALUES (值1) [… , (值n) ];
语法说明如下。
<表名>:指定被操作的表名。<列名>:指定需要插入数据的列名。若向表中的所有列插入数据,则全部的列名均可以省略,直接采用 INSERT<表名>VALUES(…) 即可。VALUES或VALUE子句:该子句包含要插入的数据清单。数据清单中数据的顺序要和列的顺序相对应。
省略字段的插入
mysql> insert into EMP values(9999,'zhangsan','MANAGER',null,null,3000,500,10);Query OK, 1 row affected (0.09 sec)mysql> select * from EMP where EMPNO=9999;+-------+----------+---------+------+----------+---------+--------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+----------+---------+------+----------+---------+--------+--------+| 9999 | zhangsan | MANAGER | NULL | NULL | 3000.00 | 500.00 | 10 |+-------+----------+---------+------+----------+---------+--------+--------+1 row in set (0.24 sec)mysql>
不建议使用此种方式,因为当数据库表中的字段位置发生改变的时候会影响到insert语句.
指定字段的插入(建议使用此种方式)
mysql> insert into EMP (EMPNO,ENAME,JOB,SAL,COMM,DEPTNO) values(9998,'lisi','MANAGER',4000,300,10);Query OK, 1 row affected (0.08 sec)mysql> select * from EMP where EMPNO=9998;+-------+-------+---------+------+----------+---------+--------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+-------+---------+------+----------+---------+--------+--------+| 9998 | lisi | MANAGER | NULL | NULL | 4000.00 | 300.00 | 10 |+-------+-------+---------+------+----------+---------+--------+--------+1 row in set (2.53 sec)
表复制
mysql> create table emp_bak as select EMPNO,ENAME,SAL from EMP;Query OK, 16 rows affected (0.11 sec)Records: 16 Duplicates: 0 Warnings: 0mysql> select * from emp_bak;+-------+----------+---------+| EMPNO | ENAME | SAL |+-------+----------+---------+| 7369 | SMITH | 800.00 || 7499 | ALLEN | 1600.00 || 7521 | WARD | 1250.00 || 7566 | JONES | 2975.00 || 7654 | MARTIN | 1250.00 || 7698 | BLAKE | 2850.00 || 7782 | CLARK | 2450.00 || 7788 | SCOTT | 3000.00 || 7839 | KING | 5000.00 || 7844 | TURNER | 1500.00 || 7876 | ADAMS | 1100.00 || 7900 | JAMES | 950.00 || 7902 | FORD | 3000.00 || 7934 | MILLER | 1300.00 || 9998 | lisi | 4000.00 || 9999 | zhangsan | 3000.00 |+-------+----------+---------+16 rows in set (0.27 sec)
删除(delete)
使用 DELETE 语句从单个表中删除数据,语法格式为:
DELETE FROM <表名> [WHERE 子句] [ORDER BY 子句] [LIMIT 子句]
语法说明如下:
<表名>:指定要删除数据的表名。ORDER BY子句:可选项。表示删除时,表中各行将按照子句中指定的顺序进行删除。WHERE子句:可选项。表示为删除操作限定删除条件,若省略该子句,则代表删除该表中的所有行。LIMIT子句:可选项。用于告知服务器在控制命令被返回到客户端前被删除行的最大值。
改(update)
使用 UPDATE 语句修改单个表,语法格式为:
UPDATE <表名> SET 字段 1=值 1 [,字段 2=值 2… ] [WHERE 子句 ][ORDER BY 子句] [LIMIT 子句]
语法说明如下:
<表名>:用于指定要更新的表名称。SET子句:用于指定表中要修改的列名及其列值。其中,每个指定的列值可以是表达式,也可以是该列对应的默认值。如果指定的是默认值,可用关键字 DEFAULT 表示列值。WHERE子句:可选项。用于限定表中要修改的行。若不指定,则修改表中所有的行。ORDER BY子句:可选项。用于限定表中的行被修改的次序。LIMIT子句:可选项。用于限定被修改的行数。
将job为manager的员工的工资上涨10%。
mysql> update EMP set SAL=SAL+SAL*0.1 where JOB='MANAGER';Query OK, 5 rows affected (0.08 sec)Rows matched: 5 Changed: 5 Warnings: 0
创建表加入约束
常见的约束
- 非空约束(not null)
- 唯一约束(unique)
- 主键约束(primary key)
- 外键约束(foreign key)
- 自定义检查约束,check(不建议使用)(在mysql中现在还不支持)
非空约束(not null)
非空约束,针对某个字段设置其值不为空,如:学生的姓名不能为空。
mysql> drop table if exists t_student;mysql> create table t_student(-> student_id int(10),-> student_name varchar(20) not null,-> sex char(2),-> birthday date,-> email varchar(30),-> classes_id int(3)-> );Query OK, 0 rows affected (0.18 sec)
唯一约束(unique)
唯一性约束,它可以使某个字段的值不能重复,如:email不能重复:
mysql> drop table if exists t_student;mysql> create table t_student(-> student_id int(10),-> student_name varchar(20) not null,-> sex char(2),-> birthday date,-> email varchar(30) unique,-> classes_id int(3)-> );Query OK, 0 rows affected (0.18 sec)
主键约束(primary key)
每个表应该具有主键,主键可以标识记录的唯一性,主键分为单一主键和复合(联合)主键,单一主键是由一个字段构成的,复合(联合)主键是由多个字段构成的。
mysql> drop table if exists t_student;mysql> create table t_student(-> student_id int(10) primary key,/*列级约束*/-> student_name varchar(20) not null,-> sex char(2),-> birthday date,-> email varchar(30) unique,-> classes_id int(3)-> );Query OK, 0 rows affected (0.18 sec)
或者是在定义完所有字段之后指定主键,语法格式如下:[CONSTRAINT <约束名>] PRIMARY KEY [字段名]
我们也可以通过表级约束为约束起个名称:
mysql> drop table if exists t_student;mysql> create table t_student(-> student_id int(10)-> student_name varchar(20) not null,-> sex char(2),-> birthday date,-> email varchar(30) unique,-> classes_id int(3),-> CONSTRAINT p_id primary key(student_id)-> );Query OK, 0 rows affected (0.18 sec)
外键约束(foreign key)
外键主要是维护表之间的关系的,主要是为了保证参照完整性,如果表中的某个字段为外键字段,那么该字段的值必须来源于参照的表的主键,如:emp中的deptno值必须来源于dept表中的deptno字段值。
建立学生和班级表之间的连接。
首先建立班级表t_classes
mysql> drop table if exists t_classes;Query OK, 0 rows affected (0.55 sec)mysql> create table t_classes(-> classes_id int(3),-> classes_name varchar(40),-> constraint pk_classes_id primary key(classes_id)-> );Query OK, 0 rows affected (0.16 sec)
SQL分类
数据查询语言(DQL-Data Query Language)
数据操纵语言(DML-Data Manipulation Language)
数据定义语言(DDL-Data Definition Language)
事务控制语言(TCL-Transactional Control Language)
数据控制语言(DCL-Data Control Language)
代表关键字:grant,revoke.
导入演示数据
使用MySQL命令行客户端来装载数据库。
1、连接MySQL数据库
连接MySQL数据库的工具有很多,自行挑选一款自己喜欢的就行了。
2、创建“bjpowernode”数据库
mysql> create database bjpowernode;Query OK, 1 row affected (0.09 sec)
3、选择数据库
mysql> use bjpowernode;Database changed
4、导入数据库
mysql> source /home/bjpowernode.sql
注意:导入sql文件之前,确保对应的目录下有该文件,而且选择了对应的数据库。
表结构介绍
表名称:dept
描述:部门信息表
| 英文字段名称 | 中文描述 | 类型 |
|---|---|---|
| DEPTNO | 部门编号 | INT(2) |
| DNAME | 部门名称 | VARCHAR(14) |
| LOC | 位置 | VARCHAR(13) |
表名称:emp
描述:员工信息表
| 英文字段名称 | 中文描述 | 类型 |
|---|---|---|
| EMPNO | 员工编号 | INT (4) |
| ENAME | 员工姓名 | VARCHAR(10) |
| JOB | 工作岗位 | VARCHAR(9) |
| MGR | 上级领导 | INT (4) |
| HIREDATE | 入职日期 | DATE |
| SAL | 薪水 | DOUBLE(7,2) |
| COMM | 津贴 | DOUBLE (7,2) |
| DEPTNO | 部门编号 | INT(2) |
注:DEPTNO字段是外键,DEPTNO的值来源于dept表的主键,起到了约束的作用
表名称:salgrade
描述:薪水等级信息表
| 英文字段名称 | 中文描述 | 类型 |
|---|---|---|
| GRADE | 等级 | INT |
| LOSAL | 最低薪水 | INT |
| HISAL | 最高薪水 | INT |
常用命令
查看msyql版本
MySQL程序选项具有以下两种通用形式:
- 长选项,由单词之前加两个减号组成
- 短选项,由单个字母之前加一个减号组成 ```shell root@mysql-server:/home# mysql -V mysql Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using EditLine wrapper root@mysql-server:/home# mysql —version mysql Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using EditLine wrapper root@mysql-server:/home#
<a name="1dksy"></a>## 创建数据库```plsqlCREATE DATABASE [IF NOT EXISTS] <数据库名>[[DEFAULT] CHARACTER SET <字符集名>][[DEFAULT] COLLATE <校对规则名>];
[]中的内容是可选的。语法说明如下:
- <数据库名>:创建数据库的名称。MySQL 的数据存储区将以目录方式表示 MySQL 数据库,因此数据库名称必须符合操作系统的文件夹命名规则,不能以数字开头,尽量要有实际意义。注意在 MySQL 中不区分大小写。
- IF NOT EXISTS:在创建数据库之前进行判断,只有该数据库目前尚不存在时才能执行操作。此选项可以用来避免数据库已经存在而重复创建的错误。
- [DEFAULT] CHARACTER SET:指定数据库的字符集。指定字符集的目的是为了避免在数据库中存储的数据出现乱码的情况。如果在创建数据库时不指定字符集,那么就使用系统的默认字符集。
- [DEFAULT] COLLATE:指定字符集的默认校对规则。
实例1:
mysql> CREATE DATABASE IF NOT EXISTS test_db_char-> DEFAULT CHARACTER SET utf8-> DEFAULT COLLATE utf8_chinese_ci;Query OK, 1 row affected (0.03 sec)
查询当前使用的数据库
mysql> select database();+------------+| database() |+------------+| test |+------------+1 row in set (0.03 sec)
查看数据库
在 MySQL 中,可使用 **SHOW DATABASES** 语句来查看或显示当前用户权限范围以内的数据库。查看数据库的语法格式为:
SHOW DATABASES [LIKE '数据库名'];例子2:mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || bjpowernode || eladmin || mysql || performance_schema || sqlalchemy || sys || test |+--------------------+8 rows in set (0.08 sec)
修改数据库
在 MySQL 中,可以使用 **ALTER DATABASE**来修改已经被创建或者存在的数据库的相关参数。修改数据库的语法格式为:
ALTER DATABASE [数据库名] {[ DEFAULT ] CHARACTER SET <字符集名> |[ DEFAULT ] COLLATE <校对规则名>}
语法说明如下:
- ALTER DATABASE 用于更改数据库的全局特性。
- 使用 ALTER DATABASE 需要获得数据库 ALTER 权限。
- 数据库名称可以忽略,此时语句对应于默认数据库。
- CHARACTER SET 子句用于更改默认的数据库字符集。
例子3:
mysql> show create database sqlalchemy;+------------+--------------------------------------------------------------------------------------+| Database | Create Database |+------------+--------------------------------------------------------------------------------------+| sqlalchemy | CREATE DATABASE `sqlalchemy` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */ |+------------+--------------------------------------------------------------------------------------+1 row in set (0.13 sec)mysql> alter database sqlalchemy-> default character set gb2312-> default collate gb2312_chinese_ci;Query OK, 1 row affected (0.09 sec)mysql> show create database sqlalchemy;+------------+-----------------------------------------------------------------------+| Database | Create Database |+------------+-----------------------------------------------------------------------+| sqlalchemy | CREATE DATABASE `sqlalchemy` /*!40100 DEFAULT CHARACTER SET gb2312 */ |+------------+-----------------------------------------------------------------------+1 row in set (0.01 sec)
删除数据库
在 MySQL 中,当需要删除已创建的数据库时,可以使用 **DROP DATABASE**语句。其语法格式为:
DROP DATABASE [ IF EXISTS ] <数据库名>
语法说明如下:
- <数据库名>:指定要删除的数据库名。
- IF EXISTS:用于防止当数据库不存在时发生错误。
- DROP DATABASE:删除数据库中的所有表格并同时删除数据库。使用此语句时要非常小心,以免错误删除。如果要使用 DROP DATABASE,需要获得数据库 DROP 权限
退出mysql
可使用\q、QUIT或EXIT
mysql> \qByeroot@mysql-server:/#
查看“演示数据”的表结构
查看和指定现有的数据库
mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || bjpowernode || eladmin || mysql || performance_schema || sqlalchemy || sys || test |+--------------------+8 rows in set (0.04 sec)
指定当前缺省数据库
mysql> use bjpowernode;Database changedmysql>
查看当前使用的库
mysql> select database();+-------------+| database() |+-------------+| bjpowernode |+-------------+1 row in set (0.08 sec)
查看当前库中的表
mysql> show tables;+-----------------------+| Tables_in_bjpowernode |+-----------------------+| DEPT || EMP || SALGRADE |+-----------------------+3 rows in set (0.08 sec)
查看其他库中的表
show tables from
如查看test库中的表
mysql> show tables from test;+----------------+| Tables_in_test |+----------------+| DEPT || EMP || SALGRADE || s1 || t1 || t2 || tx |+----------------+7 rows in set (0.05 sec)
查看表的结构
desc``<table name>;
mysql> desc EMP;+----------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+----------+-------------+------+-----+---------+-------+| EMPNO | int(4) | NO | PRI | NULL | || ENAME | varchar(10) | YES | | NULL | || JOB | varchar(9) | YES | | NULL | || MGR | int(4) | YES | | NULL | || HIREDATE | date | YES | | NULL | || SAL | double(7,2) | YES | | NULL | || COMM | double(7,2) | YES | | NULL | || DEPTNO | int(2) | YES | | NULL | |+----------+-------------+------+-----+---------+-------+8 rows in set (0.08 sec)
查看表的创建语句
show create table <table name>;
......| EMP | CREATE TABLE `EMP` (`EMPNO` int(4) NOT NULL,`ENAME` varchar(10) COLLATE utf8_bin DEFAULT NULL,`JOB` varchar(9) COLLATE utf8_bin DEFAULT NULL,`MGR` int(4) DEFAULT NULL,`HIREDATE` date DEFAULT NULL,`SAL` double(7,2) DEFAULT NULL,`COMM` double(7,2) DEFAULT NULL,`DEPTNO` int(2) DEFAULT NULL,PRIMARY KEY (`EMPNO`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin |....
简单的查询
查询一个字段
mysql> select ENAME from EMP;+--------+| ENAME |+--------+| SMITH || ALLEN || WARD || JONES || MARTIN || BLAKE || CLARK || SCOTT || KING || TURNER || ADAMS || JAMES || FORD || MILLER |+--------+14 rows in set (0.52 sec)mysql>
查询多个字段
查询员工的编号和姓名
mysql> select EMPNO,ENAME from EMP;+-------+--------+| EMPNO | ENAME |+-------+--------+| 7369 | SMITH || 7499 | ALLEN || 7521 | WARD || 7566 | JONES || 7654 | MARTIN || 7698 | BLAKE || 7782 | CLARK || 7788 | SCOTT || 7839 | KING || 7844 | TURNER || 7876 | ADAMS || 7900 | JAMES || 7902 | FORD || 7934 | MILLER |+-------+--------+14 rows in set (0.54 sec)
查询全部字段
可以将所有的字段放到select语句的后面,这种方案不方便,但是比较清楚,我们可以采用如下便捷的方式查询全部字段
mysql> select * from EMP;+-------+--------+-----------+------+------------+---------+---------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+-----------+------+------------+---------+---------+--------+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 || 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 || 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 || 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 || 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 || 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 || 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |+-------+--------+-----------+------+------------+---------+---------+--------+14 rows in set (0.32 sec)mysql>
计算员工的年薪
列出员工的编号,姓名和年薪
mysql> select EMPNO,ENAME,SAL*12 from EMP;+-------+--------+----------+| EMPNO | ENAME | SAL*12 |+-------+--------+----------+| 7369 | SMITH | 9600.00 || 7499 | ALLEN | 19200.00 || 7521 | WARD | 15000.00 || 7566 | JONES | 35700.00 || 7654 | MARTIN | 15000.00 || 7698 | BLAKE | 34200.00 || 7782 | CLARK | 29400.00 || 7788 | SCOTT | 36000.00 || 7839 | KING | 60000.00 || 7844 | TURNER | 18000.00 || 7876 | ADAMS | 13200.00 || 7900 | JAMES | 11400.00 || 7902 | FORD | 36000.00 || 7934 | MILLER | 15600.00 |+-------+--------+----------+14 rows in set (0.90 sec)mysql>
将查询出来的字段显示为中文
mysql> select EMPNO as '员工编号',ENAME as '员工姓名', SAL*12 as '年薪' from EMP;+----------+----------+----------+| 员工编号 | 员工姓名 | 年薪 |+----------+----------+----------+| 7369 | SMITH | 9600.00 || 7499 | ALLEN | 19200.00 || 7521 | WARD | 15000.00 || 7566 | JONES | 35700.00 || 7654 | MARTIN | 15000.00 || 7698 | BLAKE | 34200.00 || 7782 | CLARK | 29400.00 || 7788 | SCOTT | 36000.00 || 7839 | KING | 60000.00 || 7844 | TURNER | 18000.00 || 7876 | ADAMS | 13200.00 || 7900 | JAMES | 11400.00 || 7902 | FORD | 36000.00 || 7934 | MILLER | 15600.00 |+----------+----------+----------+14 rows in set (0.39 sec)
条件查询
条件查询需要用到where语句,where必须放到from语句表的后面。
支持如下运算符
| 运算符 | 说明 |
|---|---|
| = | 等于 |
| <>或!= | 不等于 |
| < | 小于 |
| <= | 小于等于 |
| > | 大于 |
| >= | 大于等于 |
| between … and …. | 两个值之间,等同于 >= and <= |
| is null | 为null(is not null 不为空) |
| and | 并且 |
| or | 或者 |
| in | 包含,相当于多个or(not in不在这个范围中) |
| not | not可以取非,主要用在is 或in中 |
| like | like称为模糊查询,支持%或下划线匹配 %匹配任意个字符 下划线,一个下划线只匹配一个字符 |
等号操作符
查询薪水为5000的员工
mysql> select EMPNO,ENAME,SAL from EMP where SAL=5000;+-------+-------+---------+| EMPNO | ENAME | SAL |+-------+-------+---------+| 7839 | KING | 5000.00 |+-------+-------+---------+1 row in set (0.19 sec)
<>操作符
查询薪水不等于5000的员工
mysql> select EMPNO,ENAME,SAL from EMP where SAL<>5000;+-------+--------+---------+| EMPNO | ENAME | SAL |+-------+--------+---------+| 7369 | SMITH | 800.00 || 7499 | ALLEN | 1600.00 || 7521 | WARD | 1250.00 || 7566 | JONES | 2975.00 || 7654 | MARTIN | 1250.00 || 7698 | BLAKE | 2850.00 || 7782 | CLARK | 2450.00 || 7788 | SCOTT | 3000.00 || 7844 | TURNER | 1500.00 || 7876 | ADAMS | 1100.00 || 7900 | JAMES | 950.00 || 7902 | FORD | 3000.00 || 7934 | MILLER | 1300.00 |+-------+--------+---------+13 rows in set (0.25 sec)
between … and …操作符
查询薪水为1600到3000的员工(第一种方式,采用>=和<=)
mysql> select EMPNO,ENAME,SAL from EMP where SAL >=1600 and SAL <=3000;+-------+-------+---------+| EMPNO | ENAME | SAL |+-------+-------+---------+| 7499 | ALLEN | 1600.00 || 7566 | JONES | 2975.00 || 7698 | BLAKE | 2850.00 || 7782 | CLARK | 2450.00 || 7788 | SCOTT | 3000.00 || 7902 | FORD | 3000.00 |+-------+-------+---------+6 rows in set (0.25 sec)
查询薪水为1600到3000的员工(第一种方式,采用between … and …)
mysql> select EMPNO,ENAME,SAL from EMP where SAL between 1600 and 3000;+-------+-------+---------+| EMPNO | ENAME | SAL |+-------+-------+---------+| 7499 | ALLEN | 1600.00 || 7566 | JONES | 2975.00 || 7698 | BLAKE | 2850.00 || 7782 | CLARK | 2450.00 || 7788 | SCOTT | 3000.00 || 7902 | FORD | 3000.00 |+-------+-------+---------+6 rows in set (0.24 sec)
is null
Null为空,但不是空串,为null可以设置这个字段不填值,如果查询为null的字段,采用is null
查询津贴为空的员工(因为null类型比较特殊,必须使用 is来比较)
mysql> select * from EMP where COMM is NULL;+-------+--------+-----------+------+------------+---------+------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+-----------+------+------------+---------+------+--------+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 || 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 || 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 || 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |+-------+--------+-----------+------+------------+---------+------+--------+10 rows in set (0.30 sec)
and
and表示并且的含义,表示所有的条件必须满足。
工作岗位为MANAGER,薪水大于2500的员工
mysql> select * from EMP where SAL > 2500 and JOB="MANAGER";+-------+-------+---------+------+------------+---------+------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+-------+---------+------+------------+---------+------+--------+| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |+-------+-------+---------+------+------------+---------+------+--------+2 rows in set (0.29 sec)
or
or只要满足条件即可,相当于包含。
查询出job为MANAGER或者job为ANALYST的员工。
mysql> select * from EMP where JOB ="ANALYST" or JOB="MANAGER";+-------+-------+---------+------+------------+---------+------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+-------+---------+------+------------+---------+------+--------+| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |+-------+-------+---------+------+------------+---------+------+--------+5 rows in set (0.28 sec)
表达式的优先级
- 查询薪水大于1800,并且部门代码为20或30的员工(错误的写法) ```plsql mysql> select * from EMP where SAL>1800 and DEPTNO=20 or DEPTNO=30; +———-+————+—————+———+——————+————-+————-+————+ | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | +———-+————+—————+———+——————+————-+————-+————+ | 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 | | 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 | | 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 | | 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 | | 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 | | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 | | 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 | | 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 | | 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 | +———-+————+—————+———+——————+————-+————-+————+ 9 rows in set (0.27 sec)
以上输出不是预期结果,薪水小于1800的数据也被查询上来了,原因是表达式的优先级导致的,首先过滤sal > 1800 and deptno = 20,然后再将deptno = 30员工合并过来,所以是不对的。- 查询薪水大于1800,并且部门代码为20或30的(正确的写法)。```plsqlmysql> select * from EMP where SAL>1800 and (DEPTNO=20 or DEPTNO=30);+-------+-------+---------+------+------------+---------+------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+-------+---------+------+------------+---------+------+--------+| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |+-------+-------+---------+------+------------+---------+------+--------+4 rows in set (0.25 sec)
in
in表示包含的意思,完全可以采用or来表示,采用in会更简洁一些。
查询出job为manager或者job为salesman的员工
mysql> select * from EMP where JOB in ('MANAGER','ANALYST');+-------+-------+---------+------+------------+---------+------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+-------+---------+------+------------+---------+------+--------+| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |+-------+-------+---------+------+------------+---------+------+--------+5 rows in set (0.67 sec)
查询出薪水包含1600和薪水包含3000的员工
mysql> select * from EMP where SAL in (1600,3000);+-------+-------+----------+------+------------+---------+--------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+-------+----------+------+------------+---------+--------+--------+| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 || 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |+-------+-------+----------+------+------------+---------+--------+--------+3 rows in set (0.42 sec)
not
查询出薪水不包含1600和薪水不包含3000的员工(第一种写法)
mysql> select * from EMP where SAL <> 1600 and SAL <>3000;+-------+--------+-----------+------+------------+---------+---------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+-----------+------+------------+---------+---------+--------+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 || 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 || 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 || 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 || 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 || 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |+-------+--------+-----------+------+------------+---------+---------+--------+11 rows in set (0.27 sec)
查询出薪水不包含1600和薪水不包含3000的员工(第二种写法)
mysql> select * from EMP where not (SAL=1600 or SAL=3000);+-------+--------+-----------+------+------------+---------+---------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+-----------+------+------------+---------+---------+--------+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 || 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 || 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 || 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 || 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 || 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |+-------+--------+-----------+------+------------+---------+---------+--------+11 rows in set (0.25 sec)
like
Like可以实现模糊查询,like支持%和下划线匹配
查询姓名以M开头所有的员工
mysql> select * from EMP where ENAME like 'M%';+-------+--------+----------+------+------------+---------+---------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+----------+------+------------+---------+---------+--------+| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 || 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |+-------+--------+----------+------+------------+---------+---------+--------+2 rows in set (0.25 sec)
排序数据
单一字段排序
排序采用order by子句,order by后面跟上排序字段,排序字段可以放多个,多个采用逗号间隔,order by默认采用升序,如果存在where子句那么order by必须放到where语句的后面
按照薪水由小到大排序(系统默认由小到大)
mysql> select * from EMP order by SAL;+-------+--------+-----------+------+------------+---------+---------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+-----------+------+------------+---------+---------+--------+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 || 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 || 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 || 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 || 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 || 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 || 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 || 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 || 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |+-------+--------+-----------+------+------------+---------+---------+--------+14 rows in set (0.29 sec)
取得job为MANAGER的员工,按照薪水由小到大排序(系统默认由小到大)
mysql> select * from EMP where JOB="MANAGER" order by SAL;+-------+-------+---------+------+------------+---------+------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+-------+---------+------+------------+---------+------+--------+| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |+-------+-------+---------+------+------------+---------+------+--------+3 rows in set (0.25 sec)
如果包含where语句order by必须放到where后面,如果没有where语句order by放到表的后面。
以下写法是错误的:select * from EMP order by SAL where JOB='MANAGER';
按照多个字段排序,如:首先按照job排序,再按照sal排序select * from EMP order by JOB,SAL;
手动指定排序顺序
手动指定按照薪水由小到大排序.
mysql> select * from EMP order by SAL ASC;+-------+--------+-----------+------+------------+---------+---------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+-----------+------+------------+---------+---------+--------+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 || 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 || 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 || 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 || 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 || 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 || 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 || 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 || 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |+-------+--------+-----------+------+------------+---------+---------+--------+14 rows in set (0.26 sec)
手动指定按照薪水由大到小排序.
mysql> select * from EMP order by SAL desc;+-------+--------+-----------+------+------------+---------+---------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+-----------+------+------------+---------+---------+--------+| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 || 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 || 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 || 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 || 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 || 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 || 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 || 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 || 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |+-------+--------+-----------+------+------------+---------+---------+--------+14 rows in set (0.25 sec)
多个字段排序
按照job和薪水倒序。
mysql> select * from EMP order by JOB,SAL desc;+-------+--------+-----------+------+------------+---------+---------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+-----------+------+------------+---------+---------+--------+| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 || 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 || 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 || 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 || 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 || 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 || 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 || 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 || 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |+-------+--------+-----------+------+------------+---------+---------+--------+14 rows in set (0.28 sec)
如果采用多个字段排序,如果根据第一个字段排序重复了,会根据第二个字段排序。
使用字段的位置来排序
按照薪水升序
mysql> select * from EMP order by 6;+-------+--------+-----------+------+------------+---------+---------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+-----------+------+------------+---------+---------+--------+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 || 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 || 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 || 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 || 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 || 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 || 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 || 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 || 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |+-------+--------+-----------+------+------------+---------+---------+--------+14 rows in set (0.33 sec)
分组函数/聚合函数/多行处理函数
| count | 取得记录数 |
|---|---|
| sum | 求和 |
| avg | 取平均 |
| max | 取最大的数 |
| min | 取最小的数 |
注意:分组函数自动忽略空值,不需要手动的加where条件排除空值。 select count(*) from emp where xxx; 符合条件的所有记录总数。 select count(comm) from emp; comm这个字段中不为空的元素总数。
注意:分组函数不能直接使用在where关键字后面。mysql> select ename,sal from emp where sal > avg(sal);ERROR 1111 (HY000): Invalid use of group function
count
取得所有的员工数
mysql> select count(*) from EMP;+----------+| count(*) |+----------+| 14 |+----------+1 row in set (0.32 sec)
Count(*)表示取得所有记录,忽略null,为null的值也会取得
取得津贴不为null员工数
mysql> select count(COMM) from EMP;+-------------+| count(COMM) |+-------------+| 4 |+-------------+1 row in set (0.24 sec)
采用count(字段名称),不会取得为null的记录
取得工作岗位的个数
mysql> select count(distinct JOB) from EMP;+---------------------+| count(distinct JOB) |+---------------------+| 5 |+---------------------+1 row in set (0.28 sec)
sum
Sum可以取得某一个列的和,null会被忽略。
取得薪水的合计
mysql> select sum(SAL) from EMP;+----------+| sum(SAL) |+----------+| 29025.00 |+----------+1 row in set (0.31 sec)mysql>
取得津贴的合计
mysql> select sum(COMM) from EMP;+-----------+| sum(COMM) |+-----------+| 2200.00 |+-----------+1 row in set (0.26 sec)
取得薪水的合计(sal+comm)
mysql> select sum(SAL+COMM) from EMP;+---------------+| sum(SAL+COMM) |+---------------+| 7800.00 |+---------------+1 row in set (0.25 sec)
从以上结果来看,不正确,原因在于comm字段有null值,所以无法计算,sum会忽略掉,正确的做法是将comm字段转换成0。
mysql> select sum(SAL+IFNULL(COMM,0)) from EMP;+-------------------------+| sum(SAL+IFNULL(COMM,0)) |+-------------------------+| 31225.00 |+-------------------------+1 row in set (0.24 sec)
avg
取得某一列的平均值
取得平均薪水
mysql> select avg(SAL) from EMP;+-------------+| avg(SAL) |+-------------+| 2073.214286 |+-------------+1 row in set (0.23 sec)
max
取得某个一列的最大值
取得最高薪水
mysql> select max(sal) from EMP;+----------+| max(sal) |+----------+| 5000.00 |+----------+1 row in set (0.21 sec)
取得最晚入职得员工
mysql> select max(str_to_date(HIREDATE,'%Y-%m-%d')) from EMP;+---------------------------------------+| max(str_to_date(HIREDATE,'%Y-%m-%d')) |+---------------------------------------+| 1987-05-23 |+---------------------------------------+1 row in set (0.21 sec)
STR_TO_DATE(str,format)函数是将时间格式的字符串(str),按照所提供的显示格式(format)转换为DATETIME类型的值。
min
取得某个一列的最小值
取得最低薪水
mysql> select min(SAL) from EMP;+----------+| min(SAL) |+----------+| 800.00 |+----------+1 row in set (0.24 sec)
组合聚合函数
可以将这些聚合函数都放到select中一起使用。
mysql> select count(*),sum(SAL),avg(SAL),max(SAL),min(SAL) from EMP;+----------+----------+-------------+----------+----------+| count(*) | sum(SAL) | avg(SAL) | max(SAL) | min(SAL) |+----------+----------+-------------+----------+----------+| 14 | 29025.00 | 2073.214286 | 5000.00 | 800.00 |+----------+----------+-------------+----------+----------+1 row in set (0.23 sec)
分组查询
分组查询主要涉及到两个子句,分别是:group by和having
group by
取得每个工作岗位的工资合计,要求显示岗位名称和工资合计
mysql> select JOB,sum(SAL) from EMP group by JOB;+-----------+----------+| JOB | sum(SAL) |+-----------+----------+| ANALYST | 6000.00 || CLERK | 4150.00 || MANAGER | 8275.00 || PRESIDENT | 5000.00 || SALESMAN | 5600.00 |+-----------+----------+5 rows in set (0.29 sec)
having
如果想对分组数据再进行过滤需要使用having子句。
取得每个岗位的平均工资大于2000
mysql> select JOB,avg(SAL) from EMP group by JOB having avg(SAL)>2000;+-----------+-------------+| JOB | avg(SAL) |+-----------+-------------+| ANALYST | 3000.000000 || MANAGER | 2758.333333 || PRESIDENT | 5000.000000 |+-----------+-------------+3 rows in set (0.20 sec)mysql>
分组函数的执行顺序: 根据条件查询数据 分组 采用having过滤,取得正确的数据
select语句总结
一个完整的select语句格式如下
select 字段from 表名where …….group by ……..having …….(就是为了过滤分组后的数据而存在的—不可以单独的出现)order by ……..
以上语句的执行顺序
- 首先执行where语句过滤原始数据
- 执行group by进行分组
- 执行having对分组数据进行操作
- 执行select选出数据
- 执行order by排序 原则:能在where中过滤的数据,尽量在where中过滤,效率较高。having的过滤是专门对分组之后的数据进行过滤的。
子查询
子查询就是嵌套的select语句,可以理解为子查询是一张表
在where语句中使用子查询,也就是在where语句中加入select语句
查询员工信息,查询哪些人是管理者,要求显示出其员工编号和员工姓名
实现思路:
首先取得管理者编号,去除重复的
mysql> select distinct MGR from EMP where MGR is not null;+------+| MGR |+------+| 7902 || 7698 || 7839 || 7566 || 7788 || 7782 |+------+
查询员工编号包含管理者编号的
mysql> select EMPNO,ENAME from EMP where EMPNO in (select distinct MGR from EMP where MGR is not null);+-------+-------+| EMPNO | ENAME |+-------+-------+| 7902 | FORD || 7698 | BLAKE || 7839 | KING || 7566 | JONES || 7788 | SCOTT || 7782 | CLARK |+-------+-------+6 rows in set (0.28 sec)
查询哪些人的薪水高于员工的平均薪水,需要显示员工编号,员工姓名,薪水
实现思路:
1、取得平均薪水mysql> select avg(SAL) from EMP;+-------------+| avg(SAL) |+-------------+| 2073.214286 |+-------------+1 row in set (0.30 sec)
2、取得大于平均薪水的员工
mysql> select EMPNO,ENAME,SAL from EMP where SAL >(select avg(SAL) from EMP);+-------+-------+---------+| EMPNO | ENAME | SAL |+-------+-------+---------+| 7566 | JONES | 2975.00 || 7698 | BLAKE | 2850.00 || 7782 | CLARK | 2450.00 || 7788 | SCOTT | 3000.00 || 7839 | KING | 5000.00 || 7902 | FORD | 3000.00 |+-------+-------+---------+6 rows in set (0.30 sec)
在from语句中使用子查询,可以将该子查询看做一张表
查询员工信息,查询哪些人是管理者,要求显示出其员工编号和员工姓名。
1、首先取得管理者的编号,去除重复的。mysql> select distinct MGR from EMP where MGR is not null;+------+| MGR |+------+| 7902 || 7698 || 7839 || 7566 || 7788 || 7782 |+------+
将以上查询作为一张表,放到from语句的后面。
使用92语法:select e.empno, e.ename from emp e, (select distinct mgr from emp where mgr is not null) m where e.empno=m.mgr;使用99语法:select e.empno, e.ename from emp e join (select distinct mgr from emp where mgr is not null) m on e.empno=m.mgr;
查询各个部门的平均薪水所属等级,需要显示部门编号,平均薪水,等级编号
实现思路
1、首先取得各个部门的平均薪水mysql> select DEPTNO,avg(SAL) from EMP group by DEPTNO;+--------+-------------+| DEPTNO | avg(SAL) |+--------+-------------+| 10 | 2916.666667 || 20 | 2175.000000 || 30 | 1566.666667 |+--------+-------------+3 rows in set (0.21 sec)
2、将部门的平均薪水作为一张表与薪水等级表建立连接,取得等级
mysql> select a.DEPTNO,a.avg_sal,g.GRADE from (select DEPTNO,avg(SAL) as avg_sal from EMP group by DEPTNO) a join SALGRADE g on a.avg_sal between g.LOSAL AND g.HISAL;+--------+-------------+-------+| DEPTNO | avg_sal | GRADE |+--------+-------------+-------+| 10 | 2916.666667 | 4 || 20 | 2175.000000 | 4 || 30 | 1566.666667 | 3 |+--------+-------------+-------+3 rows in set (0.68 sec)
在select语句中使用子查询
查询员工信息,并显示出员工所属的部门名称。
第一种做法,将员工表和部门表连接。mysql> select e.ENAME,d.DNAME from DEPT d,EMP e where e.DEPTNO=d.DEPTNO;+--------+------------+| ENAME | DNAME |+--------+------------+| SMITH | RESEARCH || ALLEN | SALES || WARD | SALES || JONES | RESEARCH || MARTIN | SALES || BLAKE | SALES || CLARK | ACCOUNTING || SCOTT | RESEARCH || KING | ACCOUNTING || TURNER | SALES || ADAMS | RESEARCH || JAMES | SALES || FORD | RESEARCH || MILLER | ACCOUNTING |+--------+------------+14 rows in set (0.29 sec)
第二种做法,在select语句中再次嵌套select语句完成部分名称的查询。
mysql> select e.ENAME,(select d.DNAME from DEPT d where e.DEPTNO=d.DEPTNO) as dname from EMP e;+--------+------------+| ENAME | dname |+--------+------------+| SMITH | RESEARCH || ALLEN | SALES || WARD | SALES || JONES | RESEARCH || MARTIN | SALES || BLAKE | SALES || CLARK | ACCOUNTING || SCOTT | RESEARCH || KING | ACCOUNTING || TURNER | SALES || ADAMS | RESEARCH || JAMES | SALES || FORD | RESEARCH || MILLER | ACCOUNTING |+--------+------------+14 rows in set (0.59 sec)
union
union可以合并集合(相加)
查询job包含MANAGER和包含SALESMAN的员工。 ```plsql mysql> select * from EMP where JOB in (“SALESMAN”,”MANAGER”); +———-+————+—————+———+——————+————-+————-+————+ | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | +———-+————+—————+———+——————+————-+————-+————+ | 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 | | 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 | | 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 | | 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 | | 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 | | 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 | | 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 | +———-+————+—————+———+——————+————-+————-+————+ 7 rows in set (0.24 sec)
mysql>
采用union来合并```plsqlmysql> select * from EMP where JOB="SALESMAN"-> union-> select * from EMP where JOB="MANAGER";+-------+--------+----------+------+------------+---------+---------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+----------+------+------------+---------+---------+--------+| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 || 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 || 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 || 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 || 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |+-------+--------+----------+------+------------+---------+---------+--------+7 rows in set (0.24 sec)
limit 的使用
mySql提供了limit ,主要用于提取前几条或者中间某几行数据。select * from table limit m,n
其中m是指记录开始的index,从0开始,表示第一条记录 n是指从第m+1条开始,取n条。
取得前5条数据
mysql> select * from EMP limit 5;+-------+--------+----------+------+------------+---------+---------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+--------+----------+------+------------+---------+---------+--------+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 || 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 || 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |+-------+--------+----------+------+------------+---------+---------+--------+5 rows in set (0.22 sec)
从第二条开始取两条数据
mysql> select * from EMP limit 1,2;+-------+-------+----------+------+------------+---------+--------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+-------+----------+------+------------+---------+--------+--------+| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 || 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |+-------+-------+----------+------+------------+---------+--------+--------+2 rows in set (0.22 sec)
取得薪水最高的前5名
mysql> select * from EMP order by SAL desc limit 5;+-------+-------+-----------+------+------------+---------+------+--------+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |+-------+-------+-----------+------+------------+---------+------+--------+| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 || 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 || 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 || 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 || 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |+-------+-------+-----------+------+------------+---------+------+--------+5 rows in set (0.19 sec)
