数据库的初步使用
MYSQL服务的开关:
第一种方式:
右键我的电脑----->管理----->服务和应用进程----->服务 找到mysql 打开和关闭
services.msc 可以替代查找服务的过程 找到mysql 打开和关闭
第二种方式:
Net start mysql服务的名称
Net stop mysql服务的名称
服务器的常用命令:
进入服务器后 mysql -u 用户名 -p 密码(可以不写的: -h 空格访问的ip -P 端口号(mysql默认端口号 3306))
本机:localhost 或 127.0.0.1
查看服务器下有那些库:
show databases;
默认有的库建议都不要去动
添加一个库:
create database 库名;
删除一个库:
drop database 库名;
进入一个库,使用一个库:
use 库名
库名可以重命名吗?
不可以!!!
查看当前库有那些表
show tables;
还没有创建表,所以是empty,空
SQL命令:
分类:
DDL:数据定义语言
主要有三个命令:
create:用于创建表,数据库中的表或其他对象的视图
create table 表名(字段1 类型 约束,字段名2 类型 约束......);
alter:此命令用于修改现有的数据库对象,如表
给表添加字段:alter table 表名 add column 字段名 字段类型;
更改字段的类型: alter table 表名 modify column 字段名 新类型;
查看表的详细信息:desc 表名;
drop:drop用于删除表,数据库中的表或其他对象的视图
drop table 表名;
DML:数据操作语言
数据操作语言中主要有三个命令:
insert:此命令用于添加,创建记录
往表里添加内容:insert into 表名 values(根据字段的顺序添加值);
update:用于更新,修改记录
修改表数据:update 表名 set 字段名1=值1,字段2=值2...where条件判断
delete:用于删除记录
删除数据:delete from 表名 where 条件判断
DQL:数据查询语言
主要的:select命令
select:用于从一个或多个表中检索某些记录
查询表的类容:select * from 表名(存在当前库中) where 条件 (查询表中的所有字段)
DCL:数据控制语言
用来定义数据库的访问权限和安全级别,及创建用户
增删查改
增加 insert 语句:
1、插入部分列的值
语法:insert into 表名(列名1,列名2...) values(值1,值2...);
2.插入全部列的值
语法:INSERT INTO 表名 VALUES(值1,值2...值n);
3.表数据移植
语法:INSERT INTO 新表名[(列名1,列名2...列名n)] SELECT 列名1,列名2...列名n FROM 旧表名 WHERE condition;
删除 delete 语句:
1.删除全部列
语法:DELETE FROM 表名;
2.删除部分列
语法:DELETE FROM 表名 WHERE condition;
修改 update 语句:
1.修改全部列的值
语法:UPDATE 表名 SET 列名1=值1,列名2=值2...列名n=值n;
2.修改指定数据的值
语法:UPDATE 表名 SET 列名1=值1,列名2=值2...列名n=值n WHERE condition;
查询 select 语句:
1.查询全部列的值
语法:SELECT 列名1,列名2...列名n FROM 表名;
SELECT * FROM 表名;
2.查询部分列的值
语法:SELECT 列名1,列名2...列名n FROM 表名 WHERE condition;
-- insert
INSERT INTO test8
VALUES
(
10,
"JJ",
"2019-06-27 10:55:00"
);
INSERT INTO test8 (NAME, birthdate)
VALUE
("JJ", "2019-06-27 10:55:00");
INSERT INTO test8 (NAME)
VALUE
("JJ");
-- insert into test7 select * from test8;
INSERT INTO test8 (id, NAME) SELECT
*
FROM
test7;
-- delete
DELETE
FROM
test8;
DELETE
FROM
test8
WHERE
birthdate = "2019-06-27 10:55:00";
-- update
UPDATE test8
SET birthdate = "2019-06-27 11:00:00";
UPDATE test8
SET NAME = "Jz",
birthdate = "2019-06-27 11:00:00"
WHERE
birthdate = "2019-06-27 10:55:00";
-- select
SELECT
*
FROM
test8;
SELECT
id,
NAME,
birthdate
FROM
test8;
SELECT
id,
NAME
FROM
test8;
SELECT
id,
NAME
FROM
test8
WHERE
NAME = "Jz";
约束:
在表的数据列上强制执行的规则。
NOT NULL 约束:不能有 NULL 值。
语法:字段名 类型 not null
NULL与没有数据是不一样的,它代表着未知的数据。
DEFAULT 约束:没有指定值时,提供默认值。
语法:字段名 类型 default 值
在 INSERT INTO 语句没有提供一个特定的值时,为列提供一个默认值。
UNIQUE 约束:字段值是不同的。
语法:字段名 类型 unique [列级约束]
[constraint 约束名] unique(字段名) [表级约束]
[constraint 约束名] unique(字段名1,字段名2...) [联合约束]
防止在一个特定的列存在两个记录具有相同的值。
PRIMARY KEY约束:唯一标识。
语法:字段名 类型 primary key [列级约束]
[constraint 约束名] primary key(字段名) [表级约束]
[constraint 约束名] primary key(字段名1,字段名2...) [联合约束]
一个表只能有一个主键约束,不能有 NULL 值,且字段值不能相同。
设计数据库表时,主键是很重要的。
主键自动递增:auto_increment 自动生成主键值,主键值不用用户维护,自动生成,自增数从1开始,以1递增。
FOREIGN KEY约束:两表关系参照。
语法:foreign key(外键所在字段名) references 主表名(主表主键所在字段名)
外键约束是保证一个或两个表之间的参照完整性
外键是构建于一个表的两个字段或是两个表的两个字段之间的参照关系
CHECK 约束:满足一定条件。
语法:字段名 类型 check(条件) [列级约束]
启用检查的条件,如果条件值为 false,不能输入到表。
主键和唯一键的区别:
1.主键不能为空 2.唯一键可以有多个,但主键只能有一个.
-- 约束
-- not null 不为null
CREATE TABLE test1 (
id INT,
NAME VARCHAR (10) NOT NULL
);
INSERT INTO test1
VALUES
(1, 1);
INSERT INTO test1
VALUES
(1, NULL);
INSERT INTO test1
VALUES
(NULL, 1);
INSERT INTO test1
VALUES
(2, "");
INSERT INTO test1 (NAME)
VALUE
(5);
-- default 默认值
CREATE TABLE test2 (
id INT,
NAME VARCHAR (10) DEFAULT "没有名字"
);
INSERT INTO test2 (id)
VALUE
(1);
-- 唯一键 unique
CREATE TABLE test3 (
id INT UNIQUE,
NAME VARCHAR (10) DEFAULT "没有名字"
);
INSERT INTO test3
VALUES
(1, "张三");
INSERT INTO test3
VALUES
(2, "李四");
-- 主键 primary key
CREATE TABLE test4 (
id INT PRIMARY KEY,
NAME VARCHAR (10) DEFAULT "没有名字"
);
INSERT INTO test4
VALUES
(1, "张三");
INSERT INTO test4
VALUES
(2, "李四");
INSERT INTO test4
VALUES
(NULL, "王五");
CREATE TABLE test5 (
id INT PRIMARY KEY auto_increment,
NAME VARCHAR (10) DEFAULT "没有名字"
);
INSERT INTO test5 (NAME)
VALUE
("王麻子");
INSERT INTO test5
VALUES
(10, "小黑");
-- check 检查
CREATE TABLE test6 (
id INT CHECK id > 10,
NAME VARCHAR (10) DEFAULT "没有名字"
);
INSERT INTO test6
VALUES
(0, "jack");
CREATE TABLE test7 (
id INT NOT NULL UNIQUE,
NAME VARCHAR (10) DEFAULT "没有名字"
);
INSERT INTO test7
VALUES
(NULL, "lili");
INSERT INTO test7 (id)
VALUE
(1);
CREATE TABLE test8 (
id INT NOT NULL UNIQUE,
NAME VARCHAR (10) DEFAULT "没有名字",
birthdate datetime
);
INSERT INTO test8
VALUES
(
2,
"王五",
"2000-01-01 00:00:05"
);
数据库三范式:
三范式的作用:
约束数据库建表的规范性。
三范式的最终目标:
不存在冗余数据
第一范式:
不要向表中输入完全重复的数据(设置主键,字段不可分割),确保每一列的原子性
1.在多个字段可以被选择的情况下,作为主键的字段应该选择最符合逻辑的一个,一般选择 与业务无关的字段,比如自增的Id
2.由于效率的关系,请尽量选择一个数值类型的字段或者定长字符串。
第二范式:
存在多对多关系时只有一个字段作为主键是不够的。
部分依赖,会产生冗余数据,需要分解表
第三范式:
班级名称和班级信息这一组值没有必要的重复出现,这些值并不直接依赖于学号(主键),依赖于班级号,也就是时说表中出现了传递依赖
-- 练习:
/*1.根据范式设计员工和公司的相关表,需要记录员工姓名,员工工资,公司名字,公司地址。
员工 -- 公司 多---1 关系
*/
CREATE TABLE employee (
emp_id INT PRIMARY KEY,
emp_name VARCHAR (10) NOT NULL,
emp_sal INT DEFAULT 500,
com_id INT NOT NULL,
FOREIGN KEY (com_id) REFERENCES company (com_id)
);
CREATE TABLE company (
com_id INT PRIMARY KEY,
com_name VARCHAR (30) NOT NULL,
com_address VARCHAR (50) NOT NULL
) /*
2.根据范式设计学生和选修课的相关表,需要记录学生姓名,学生年龄,科目名称,科目学分.
学生--选修课 多--多
*/
CREATE TABLE stu (
stu_id INT PRIMARY KEY,
stu_name VARCHAR (10) NOT NULL,
stu_age INT
);
CREATE TABLE cour (
cou_id INT PRIMARY KEY,
cou_name VARCHAR (20) NOT NULL,
cou_score INT
);
CREATE TABLE stu_cou (
stu_cou_id INT PRIMARY KEY,
stu_id INT NOT NULL,
cou_id INT NOT NULL,
FOREIGN KEY (stu_id) REFERENCES stu (stu_id),
FOREIGN KEY (cou_id) REFERENCES cour (cou_id),
UNIQUE (stu_id, cou_id)
)
运算符
-- + - * / %
SELECT
12.5 % "11s4";
-- = != <> > < >= <=
SELECT
5 != 10;
SELECT
5 = 10;
-- and
SELECT
*
FROM
emp
WHERE
sal > 2000
AND deptno = 20;
-- between
SELECT
*
FROM
emp
WHERE
sal BETWEEN 2000
AND 3000;
-- exists
SELECT
*
FROM
emp
WHERE
EXISTS (
SELECT
*
FROM
emp
WHERE
deptno = 20
) -- in
SELECT
*
FROM
emp
WHERE
sal IN (1000, 2000, 3000);
-- not in
SELECT
*
FROM
emp
WHERE
sal NOT IN (1000, 2000, 3000);
-- not
SELECT
*
FROM
emp
WHERE
NOT EXISTS (
SELECT
*
FROM
emp
WHERE
deptno = 20
) -- or
SELECT
*
FROM
emp
WHERE
job = "manager"
OR deptno = 30;
-- is null
SELECT
*
FROM
emp
WHERE
comm IS NULL;
SELECT
*
FROM
emp
WHERE
comm IS NOT NULL;
-- 关键字
-- like _ 代表一个字符 % 代表0-n个字符
SELECT
*
FROM
emp
WHERE
ename LIKE "s%" SELECT
*
FROM
emp
WHERE
ename LIKE "%h%" SELECT
*
FROM
emp
WHERE
ename LIKE "%t_" -- as 别名 简化字段名称 辨别相同表的字段
SELECT
123456789 + 987654321 AS "运算结果";
SELECT
123456789 + 987654321 "运算结果";
SELECT
e1.ename
FROM
emp e1,
emp e2
WHERE
e1.sal > e2.sal -- limit 分页
SELECT
*
FROM
emp
LIMIT 5;
SELECT
*
FROM
emp
LIMIT 3 OFFSET 6;
-- 排序 asc 升序 默认 desc 降序 可以组合使用
SELECT
*
FROM
emp
ORDER BY
empno ASC;
SELECT
*
FROM
emp
ORDER BY
empno DESC;
SELECT
*
FROM
emp
ORDER BY
mgr DESC,
ename;
-- 分组 group by
SELECT
deptno,
count(*)
FROM
emp
GROUP BY
deptno
HAVING
count(*) = 5;
-- 去重
SELECT DISTINCT
sal
FROM
emp
关键字
条件:
关键字:where having
where子句在所选列上设置条件,having子句在group by子句创建的分组上设置条件
匹配:
关键字:like
通配符:
like: '_' 代表一个单一的数字或字符 '%'代表零个、一个或者多个数字或字符
别名:
关键字: as
表别名例子: select e.ename,e. job from emp [as] e;
列别名例子: select e.ename [as] 名字,e. job [as] 工作 from emp [as] e;
分页:
关键字:limit
语法:limit rows_number offset start_rows
例子: select * from emp limit 5 offset 2;
排序:
关键字:order by [asc | desc]
语法:order by 字段1,字段2...字段n [asc | desc]
单个排序例子: select * from emp order by ename asc;
多个排序例子: select * from emp order by ename asc, sal desc;
分组:
关键字:group by
语法:group by 字段1,字段2...字段n
单个排序例子: select * from emp group by ename ;
多个排序例子: select * from emp group by ename order by sal desc;
去重:
关键字:distinct
语法:select distinct 字段1,字段2...字段n from emp;
单个去重例子: select distinct sal from emp ;
多个去重例子: select distinct ename,sal from emp ;
顺序:
语法顺序:
select -> distinct -> from -> join on -> where -> group by -> having -> union -> order by [asc|desc] -> limit
执行顺序:
from -> join on -> where -> group by -> having -> select -> distinct -> union -> order by [asc|desc] -> limit
小练习:
-- 小练习:
-- 1.查询emp表所有员工信息
SELECT
*
FROM
emp;
-- 2.查询emp表所有员工的编号
SELECT
empno,
ename
FROM
emp;
-- 3.查询员工的编号和姓名
SELECT
empno,
ename
FROM
emp;
-- 4.查询员工编号和姓名并且字段名显示成”员工编号”和”员工姓名”
SELECT
empno "员工编号",
ename "员工姓名"
FROM
emp;
-- 5.查询部门30的人员的员工姓名和工资,并且不能有重复数据
SELECT DISTINCT
ename,
sal
FROM
emp
WHERE
deptno = 30 -- 6.查询员工奖金为null的员工
SELECT
*
FROM
emp
WHERE
comm IS NULL;
-- 7.查询员工奖金不为null的而员工
SELECT
*
FROM
emp
WHERE
comm IS NOT NULL;
-- 8.查询工资是800或1250或1500或2000的员工
SELECT
*
FROM
emp
WHERE
sal IN (800, 1250, 2000);
-- 9.查询员工的姓名叫‘SMITH’或 ‘ALLEN’或 ‘KING’的员工姓名和工资
SELECT
ename,
sal
FROM
emp
WHERE
ename IN ('SMITH', 'ALLEN', 'KING');
SELECT
ename,
sal
FROM
emp
WHERE
ename = 'SMITH'
OR ename = 'ALLEN'
OR ename = 'KING';
-- 10.查询工资在1000~2500之间的员工姓名和工资和员工编号
SELECT
ename,
sal,
empno
FROM
emp
WHERE
sal BETWEEN 1000
AND 2500;
-- 11.查询不是10部门的员工姓名和工资
SELECT
ename,
sal,
deptno
FROM
emp
WHERE
deptno != 10;
SELECT
ename,
sal,
deptno
FROM
emp
WHERE
deptno <> 10;
SELECT
ename,
sal,
deptno
FROM
emp
WHERE
deptno NOT IN (10);
SELECT
ename,
sal,
deptno
FROM
emp
WHERE
deptno = 20
OR deptno = 30;
-- 12.查询入职时间晚于1984-09-01的员工编号,员工姓名,入职时间
SELECT
empno,
ename,
hiredate
FROM
emp
WHERE
hiredate > "1984-09-01";
-- 13.查询是10部门并且工资大于1000的员工的姓名,工资,部门编号
SELECT
ename,
sal,
deptno
FROM
emp
WHERE
deptno = 10
AND sal > 1000;
-- 14.查询是第10部门或者职务是CLERK 的员工所有信息
SELECT
*
FROM
emp
WHERE
deptno = 10
OR job = "CLERK";
-- 15.查询工资不是800, 1500, 2000中一个的员工所有信息
SELECT
*
FROM
emp
WHERE
sal NOT IN (800, 1500, 2000);
-- 16.列出deptno为10或者30,并且工资>2000的所有人
SELECT
*
FROM
emp
WHERE
sal > 2000
AND (deptno = 30 OR deptno = 10);
函数
函数一般是在数据上执行的,它给数据的转换和处理提供了方便。只是将取出的数据进行处理,不会改变数据库中的值。
Sql函数可以分为组函数和单行函数。
组函数又被称作聚合函数,用于对多行数据进行操作,并返回一个单一的结果,组函数仅可用于选择列表或查询的having子句
单行函数对单个数值进行操作,并返回一个值。
单行函数示意图
字符函数
字符函数全以字符作为参数,返回值分为两类:一类返回字符值,一类返回数字值
concat(string1,string2,str……)连接两个至n个字符串
Lower(string) 以小写形式返回string
upper(string)以大写形式返回string
lpad,rpad 填充字符型数据
ltrim/rtrim ()
trim() 也可以删除首尾指定字符 both|leading|trailing 字符 from 字符串
substr 提取字符串的一部分substr(string,1,2)
instr 字符串出现的位置, instr( string ,’A‘)
length 字符串长度
数字函数
round(number,n) 取舍
select round(23.652) from dual;
select round(23.652, 2) from dual;
select round(23.652, -1) from dual;
mod(x,y)求余数
select mod(13,5) from dual;
ceil()上取整
select ceil(19.2) from dual;
floor()下取整
select floor(19.9) from dual;
日期函数
Sysdate()[now()] 获取当前年月日 时分秒
Current_time() 获取当前时分秒
Current_date() 获取当前年月日
Last_day(d)获取该月最后一天
To_days(d) 从0年到现在的天数
Datediff(d1,d2) d1-d2的天数
1.Date -> String
函数:DATE_FORMAT(date,format) date:需要转换的日期 format:格式化的样式 YYYY-mm-dd HH:mm:ss %Y-%m-%d %H:%m:%s
format样式整理:
年: %Y 显示四位 : 2015 %y 只显示后两位 :15
月: %M 月份的英文显示:October %m 月份的阿拉伯显示:01-12 %b 月份的英文缩略显示:Oct %c 月份的阿拉伯显示:1-12
日: %d 阿拉伯显示:00-31 %D 带有英文后缀:1st-31th %e 阿拉伯显示:1-31 %j 年的天:001-366
时: 00-23:%H %k 01-12:%h %I %l 分: %i:00-59
秒: %S:00-59 %s:00-59 微妙: %f
AM/PM: %p 12小时制时间:%r: 02:02:44 PM 24小时制时间: %T: 14:02:44
周: %W:周的英文显示 %w 周的阿拉伯显示 :0(星期日)-6(星期六) %a 周的英文缩略显示:Mon-
eg:DATE_FORMAT(now(),"%Y-%m-%d %T") 2018-11-22 10:15:52
DATE_FORMAT(now(),"%Y-%m-%d %H:%i:%s %p") 2015-09-01 17:10:52 PM
2.String ——>Date
使用的函数:STR_TO_DATE(str,format) str:字符形式的日期 format:格式化样式
eg: STR_TO_DATE('1992-04-12',"%Y-%m-%d") 输出:1992-04-12(日期形式)
extract(unit from d) 获取日期中的详细信息
unit 取值:
SECOND 秒 MINUTE 分 HOUR 时 DAY 天
WEEK 周 MONTH 月 QUARTER 季度 YEAR 年
组函数
组函数基于多行数据返回单个值
• avg()返回某列的平均值
• min()返回某列的最小值
• max()返回某列的最大值
• sum()返回某列值的和
• count()返回某列的行数
• 组函数仅在选择列表和Having子句中有效
• 组函数除了count(*)外,都跳过空值而处理非空值
– select count(*) from emp;
– select count(comm) from emp;
ifnull(参数,值) 如果参数是null 显示出来的值 就是函数第二个参数
组函数一般结合分组使用
– group by 子句
– Group by 子句可以包含任意数目的列。
• 除组函数语句外,select语句中的每个列都必须在group by 子句中给出。(oracle特性,mysql不是)
– 如果分组列中具有null值,则null将作为一个分组返回。如果列中有多行null值,他们将分为一组。
– Group by 子句必须出现在where子句之后,order by 子句之前。
• 过滤分组(having子句)
– Where过滤行,having过滤分组。
– Having支持所有where操作符。
where 后面不能直接跟组函数
• SELECT distinct column, group_function
• FROM table
• [WHERE condition]
• [GROUP BY group_by_expression Having ….]
• [ORDER BY column];
• 使用GROUP BY子句将表分成小组
• 结果集隐式按升序排列,如果需要改变排序方式可以使用Order by 子句
出现在SELECT列表中的字段,如果出现的位置不是在组函数中,那么必须出现在GROUP BY子句中
不能在 WHERE 子句中使用组函数.不能在 WHERE 子句中限制组. 使用Having 对分组进行限制
-- 字符+数字函数练习
-- 1.查询所有员工,在员工姓名不足5个字母的右边添上X
SELECT
empno,
rpad(ename, 5, 'X') ename,
job,
mgr,
hiredate,
sal,
comm,
deptno
FROM
emp -- 2.在员工姓名不足5个字母的左边添上Y
SELECT
lpad(ename, 5, 'Y')
FROM
emp
WHERE
length(ename) < 5 -- 3.只显示员工姓名的第一个字母和编号
SELECT
empno,
substring(ename, 1, 1)
FROM
emp -- 4.使10部门的员工姓名都加上自身职位 如‘SMITH’ 变成‘SMITH-CLERK’,并查询10部门员工编号,姓名,部门号
SELECT
empno,
concat(ename, '-', job),
deptno
FROM
emp
WHERE
deptno = 10 -- 5.使20部门的员工姓名不满6个字符的在尾部填充‘X’,并查询20部门名字改变后的员工编号,姓名,部门号
SELECT
empno,
rpad(ename, 6, 'X'),
deptno
FROM
emp
WHERE
deptno = 20;
-- 6.查询名字包含A或者S的员工姓名,并在2个字段分别显示A的位置和S的位置
SELECT
ename,
instr(ename, 'S'),
instr(ename, 'A')
FROM
emp
WHERE
ename LIKE '%A%'
OR ename LIKE '%S%' -- 7.查询员工姓名,工资,工资以单位K显示。如 5320.00 -> 5K
SELECT
ename,
concat(round(sal / 1000), "K")
FROM
emp;
-- 练习:
-- 1.查询入职当月只有28天的员工,显示全部信息
SELECT
*
FROM
emp
WHERE
MONTH (hiredate) = 2 -- 2.查询年薪,年薪单位K,按年薪从高到低排序
SELECT
concat(round((sal * 12 / 1000)), 'K'),
ename,
sal
FROM
emp
ORDER BY
concat(round((sal * 12 / 1000)), 'K') DESC -- 3.查询入职到现在员工总共工资,并显示姓名
SELECT
ename,
DATEDIFF(now(), hiredate) * sal / 30
FROM
emp -- 4.查询最高薪水的员工信息
SELECT
*
FROM
emp
WHERE
sal = (SELECT max(sal) FROM emp) SELECT
*
FROM
emp
ORDER BY
sal DESC
LIMIT 1;
-- 5.以指定格式显示员工的佣金(格式:ALLEN 's comm is 300)
SELECT
concat(
ename,
' \'s comm is ',
round(ifnull(comm, 0))
)
FROM
emp -- 6.以首字母大写,其他字母小写的方式显示所有员工的姓名
SELECT
concat(
substr(ename, 1, 1),
lower(substr(ename, 2))
)
FROM
emp -- 7.查询所有12月份入职的员工
SELECT
*
FROM
emp
WHERE
date_format(hiredate, "%m") = 12;
-- 8.查询姓名不带有”R”的员工
SELECT
*
FROM
emp
WHERE
instr(ename, 'R') = 0;
-- 9.查询下半年入职的员工
SELECT
*
FROM
emp
WHERE
date_format(hiredate, "%m") > 6;
-- 10.显示所有员工的姓名,工作和薪金,按工作的降序排序,若工作相同则按薪金排序
SELECT
ename,
job,
sal
FROM
emp
ORDER BY
job DESC,
sal DESC;
-- 11.查询每个员工加入公司的天数
SELECT
datediff(now(), hiredate),
ename
FROM
emp -- 12.查询员工日薪(1个月30天,不算奖金)
SELECT
empno,
round(sal / 30)
FROM
emp -- 13.查询所有员工,并且用“x” 替换所有的 “A”
SELECT
empno,
REPLACE (ename, "A", "x")
FROM
emp -- 14.查询各月倒数第三天受雇的所有员工
SELECT
*
FROM
emp
WHERE
datediff(
last_day(hiredate),
hiredate
) = 2;
-- 15.显示姓名中没有'L'字或含有'SM'字的员工信息
SELECT
*
FROM
emp
WHERE
ename NOT LIKE '%L%'
OR ename LIKE "%SM%"