数据库对于每一个开发人员都是必须学习和深入掌握的一门技术,下面是在上课的过程中留下的MySQL笔记,提供学员参考学习。该笔记深度解析了MySQL的学习语法,愿学员能有所收获
1、MySQL安装成功后的进入方式
/第一种方式进入:
点击开始--->所有程序--->Mysql-->Mysql Server5.0--->Mysql Command Line Client 点击
提示Enter password: root 回车
即可进入Mysql操作界面:
show databases;//显示所有的数据库
use test;//选择并使用test数据库
show tables;//显示test库中所有表
exit 退出
第二种进入方式:
开始--运行输入cmd 回车
cd/进入 c盘根目录
cd 切换到:
C:/Program Files/MySQL/MySQL Server 5.0/bin>
在此目录中采用
mysql - u root -p
mysql -h 127.0.0.1 -u root -p root
回车
提示Enter password: root 回车
即可进入Mysql操作界面:
show databases;//显示所有的数据库
use test;//选择并使用test数据库
show tables;//显示test库中所有表
exit 退出
第三种方式进入:
开始--运行输入cmd 回车
cd/进入 c盘根目录
cd 切换到:
C:/Program Files/MySQL/MySQL Server 5.0/bin>
在此目录中采用
mysql - u root -p 数据库名称
mysql -h 127.0.0.1 -u root -p root 数据库名称
回车
即可进入Mysql操作界面: 在此种直接可以使用 book数据库
show tables;//显示test库中所有表
exit 退出
2、密码设置:
当用户没有设置密码时:
添加密码:
mysqladmin -uroot -password ab12
注:因为开始时root没有密码,所以-p旧密码一项就可以省略了。
当用户存在密码时:
修改密码:
cd/进入 c盘根目录
cd 切换到:
C:/Program Files/MySQL/MySQL Server 5.0/bin>
采用命令:
mysqladmin -uroot -proot password 123
回车后密码及更新为123;
3、增加用户:
(注意:和上面不同,下面的因为是MYSQL环境中的命令,所以后面都带一个分号作为命令结束符)
格式:grant select on 数据库.* to 用户名@登录主机 identified by “密码”
第一种:
增加一个用户test1密码为abc,让他可以在任何主机上登录,并对所有数据库有查询、插入、修改、删除的权限。首先用以root用户连入MYSQL,然后键入以下命令:
grant select,insert,update,delete on *.* to test1@“%” Identified by “abc”;
但增加的用户是十分危险的,你想如某个人知道test1的密码,那么他就可以在internet上的任何一台电脑上登录你的mysql数据库并对你的数据可以为所欲为了,解决办法见例第二种:
第一种:增加一个用户test2密码为abc,让他只可以在localhost上登录,并可以对数据库mydb进行查询、插入、修改、删除的操作(localhost指本地主机,即MYSQL数据库所在的那台主机),这样用户即使用知道test2的密码,他也无法从internet上直接访问数
mysql> grant select,insert,update,delete on book.* to test2@localhost Identified by "abc";
如果你不想test2有密码,可以再打一个命令将密码消掉。
mysql> grant select,insert,update,delete on book.* to test2@localhost Identified by "";
下面来看看MYSQL中有关数据库方面的操作。注意:必须首先登录到MYSQL中,以下操作都是在MYSQL的提示符下进行的,而且每个命令以分号结束。
desc admin;//显示表的结构 字段 字段类型 字段是否为null 是否是主键 额外信息等
create database 数据库名称;//创建数据库
show databases;//查看创建数据库是否成功 显示所有数据库的名称
use 数据库名称;//使用此数据库
show tables;//查看此数据库中的所有表 的名称
4、表的概念:
数据库中包含一个或多个表;
表:是行和列组成的。 行称为记录,是组织数据的单位;
列被称为字段,每一个列表示记录的一个属性。
注意事项:
在特定的表中,列的名称必须是唯一的,但相同列名可以在数据库中不同的表中存在|使用。
在表中的行与列的次序是任意的。
表:是数据的集合,是用来存储数据和操作数据的逻辑结构。
案例:
学生信息表 =====>类
学号 姓名 性别 班级编号 籍贯 年龄 ====>学号 姓名 性别 班级编号 籍贯 年龄
0x01 mm m 09 beijing 20 =====>类的一个实例|对象 都对应数据库中一条记录
5、数据类型
字段的数据类型:
MySQL中提供了三种数据类型:
1、数值
2、字符串
3、日期
数值:
tinyint 非常小的整数 -128-127 1个字节
smallint 较小的整数 -2的15次方 --2的15次方减去1 2个字节
mediumint 中等大小的整数 -2的23次方 --2的23次方减去1 3个字节
int 标准的整数 -2的31次方 --2的31次方减去1 4个字节
big int 大整数 -2的63次方 --2的63次方减去1 8个字节
float 单精度浮点型 4个字节
double 双精度浮点型 8个字节
字符型:
char CHAR列的长度固定为创建表时声明的长度。长度可以为从0到255的任何值
varchar VARCHAR列中的值为可变长字符串。长度可以指定为0到65,535之间的值
binary
varbinary
BLOB是一个二进制大对象,可以容纳可变数量的数据。有4种BLOB类型:它们只是可容纳值的最大长度不同。
·tinyblob:仅255个字符
·blob:最大限制到65K字节
·mediumblob:限制到16M字节
·longblob:可达4GB
在每个MySQL的文档(从MySQL4.0开始)的介绍中,一个longblob列的最大允许长度依赖于在客户/服务器协议中可配置的最大包的大小和可用内存数。
你可能对在BLOB中存储大型文件非常谨慎,但是请放心使用,MYSQL提供了这样的灵活性!最大包的大小可容易地中的在配置文件中设置。例如:
一,Windows通过文件my.ini (在系统盘)
[mysqld]
set-variable = max_allowed_packet=10M
二,Linux通过etc/my.cnf
[mysqld]
max_allowed_packet = 16M
你能指定几乎任何你需要的大小。默认是1M。
TEXT:
有4种TEXT类型:
TINYTEXT、
TEXT、
MEDIUMTEXT 、
LONGTEXT。这些对应4种BLOB类型,有相同的最大长度和存储需求。
SET是一个字符串对象,可以有零或多个值,其值来自表创建时规定的允许的一列值。指定包括多个SET成员的SET列值时各成员之间用逗号(‘,’)间隔开。这样SET成员值本身不能包含逗号。
例如,指定为SET('one', 'two') NOT NULL的列可以有下面的任何值:
ENUM是一个字符串对象,其值来自表创建时在列规定中显式枚举的一列值。
在某些情况下,ENUM值也可以为空字符串('')或NULL:
· 如果你将一个非法值插入ENUM(也就是说,允许的值列之外的字符串),将插入空字符串以作为特殊错误值。该字符串与“普通”空字符串不同,该字符串有数值值0。后面有详细讨论。
· 如果将ENUM列声明为允许NULL,NULL值则为该列的一个有效值,并且 默认值为NULL。如果ENUM列被声明为NOT NULL,其默认值为允许的值列的第1个元素。
每个枚举值有一个索引:
· 来自列规定的允许的值列中的值从1开始编号。
· 空字符串错误值的索引值是0。这说明你可以使用下面的SELECT语句来找出分配了非法ENUM值的行:
日期类型:
DateTime YYYY-MM-DD HH:MM:SS 从1000-01-01 00:00:00 到9999-12-31 23:59:49
date YYYY-MM-DD 从1000-12-31 至 9999-12-31
timestamp YYYYMMDDHHMMSS
time HH:MM:SS
year YYYY
//通过mysql.chm 3教程中的3.3.2创建表pet
7、创建表:
需要考虑:表包含哪些内容。 列===> 行 记录
宠物表 pet 包含字段 列-->列的名称 列的数据类型 列的长度 列是否为空 列是否为主键 是否使用约束
宠物的名称:name varchar 20 null
宠物的主人:owner varchar 20 null
宠物的性别:sex char 1
宠物的种类:species varchar 20
宠物的出生日期:birth date
宠物的死亡日期:death date
创建数据库
create database educsdn; //创建数据库
show databases; //查看是否创建成功
use educsdn;//使用数据库
然后执行创建的命令
使用Transact-SQL语言创建表
creat table 表名(
字段名称 数据类型 约束条件,
字段名称 数据类型 约束条件,
字段名称 数据类型 约束条件
);
创建pet表命令如下
mysql> create table pet
-> (
-> name varchar(20),
-> owner varchar(20),
-> species varchar(20),
-> sex char(1),
-> birth date,
-> death date
-> );
Query OK, 0 rows affected (0.08 sec)
show tables;//查看表是否创建成功
desc pet;//查看表的结构
select * from pet;//查看表中的所有数据
DML语句 insert
语法形式:insert into table_name(column_name[,....n]) values(val1,val2,....n);
字符串类型 '' 引起来 date ''
//插入数据到宠物表
//插入一条完整记录
mysql> insert into pet(name,owner,species,sex,birth,death)
-> values('Claws','Gwen','cat','m','1994-03-17',null);
//插入一条完整记录
mysql> insert into pet values('Buffy','Harold','dog','f','1989-05-13',null);
//插入一条记录中部分字段数据
mysql> insert into pet(name,owner,species,sex,birth)
-> values('Fluffy','Harold','cat','f','1993-02-04');
mysql> insert into pet(name,owner)values('benben','redarmy');
//插入记录时观察日期的格式类型
mysql> insert into pet values('fang','benny','dog','m','19900827',null);
mysql> insert into pet values('Bowser','Diane','dog','m','1979.08.31','1995/07/29');
Date日期类型插入可以按照 'YYYY-MM-DD'或'YY-MM-DD'格式的字符串。这里也允许使用“不严格的”语法。例如,'98-12-31'、'98.12.31'、'98/12/31'和'98@12@31'是等价的。
DateTime日期类型插入可以按照:'YYYY-MM-DD HH:MM:SS'或'YY-MM-DD HH:MM:SS'格式的字符串。允许“不严格”语法:任何标点符都可以用做日期部分或时间部分之间的间割符。例如,'98-12-31 11:30:45'、'98.12.31 11+30+45'、'98/12/31 11*30*45'和'98@12@31 11^30^45'是等价的
批量插入:
mysql> insert into pet
-> values('Chirpy','Gwen','bird','f','1998-09-11',null),
-> ('Whistler','Gwen','bird','','1997-12-09',null);
SQL:
SQL被称为结构化查询语言(Structured Query Language )是操作和检索关系型数据库的标准语言
SQL的分类:
※ 数据定义语言(DDL),例如:CREATE、DROP、ALTER等语句。 Data Definition Language
它最基础的SQL 它用来创建数据库 修改 或者删除数据库中的各种对象。
※ 数据操作语言(DML),例如:INSERT(插入)、UPDATE(修改)、DELETE(删除)语句。Data Manipulation language 它是操纵表、视图中的数据
※ 数据查询语言(DQL),例如:SELECT语句。 Data Query language
※ 数据控制语言(DCL),例如:GRANT、REVOKE、COMMIT、ROLLBACK等语句。 Data Control Language
主要用来执行有关安全管理的操作
SQL语言包括三种主要程序设计语言类别的语句:数据定义语言(DDL),数据操作语言(DML)及数据控制语言(DCL)。
SQL功能介绍:
SQL 面向数据库执行查询;SQL 可从数据库取回数据;SQL 可在数据库中插入新的记录;SQL 可更新数据库中的数据;SQL 可从数据库删除记录;SQL 可创建新数据库;SQL 可在数据库中创建新表;SQL 可在数据库中创建存储过程;SQL 可在数据库中创建视图;SQL 可以设置表、存储过程和视图的权限。
RDBMS 指的是关系型数据库管理系统。
DQL查询语言
:select :最简单的select的是:select column_name[,....n] from 表名
//查询表全部记录 每条记录应该包含全部字段信息 //*代表的是所有的列
select * from pet; -->等价于:mysql> select name,owner,species,sex,birth,death from pet;
//指定列的查询
mysql> select name from pet;
//为列指定别名查询
mysql> select name as '姓名' from pet;
//为表指定别名查询
mysql> select p.name,p.sex '姓别' from pet as p;
//增加说明列:
mysql> select name,'This is bithday: ',birth from pet;
//使用DISTINCT关键字
mysql> select distinct(owner) from pet;
mysql> select distinct owner from pet;
//查询所有的数据 owner不重复的(也就说只出现一次) 怎么办? 在后面讲解后可以解答?
//函数:
count
mysql> select count(*) from pet;
mysql> select count(*)'总记录数是:' from pet;
//怎么实现计算
where子句的查询
语法是:select conditon from table_name where searchcondition;
where子句通过条件表达式描述关系中元组的选择条件
where子句使用的条件有:
比较运算符:> < >= <= <> =
逻辑运算符: and or not
范围运算符:between and
列表运算符:in not in
字符匹配:like not like
未知值:is null is not null
//比较运算符查询
//查询宠物的种类为cat的所欲宠物
mysql> select * from pet where species='cat';
//查询宠物的出生日期大于1998-01-01
mysql> select * from pet where birth>'1998-01-01';
//逻辑运算查询
//查询宠物的种类是dog 并且 性别为f的所有宠物
mysql> select * from pet where species='dog' and sex='f';
//查询宠物的种类是dog 或者 性别为f的所有宠物
mysql> select * from pet where species='dog' or sex='f';
//范围查询
//查询宠物的出生日期在1993-01-01 与1998-01-01之间的所有宠物
mysql> select * from pet where birth between '1993-01-01' and '1998-01-01';
mysql> select * from pet where birth>'1993-01-01' and birth<'1998-01-01';
//列表运算符
//查询宠物的种类是cat或者是bird
mysql> select * from pet where species in ('cat','bird');
//查询宠物的种类不是cat并且也不是bird
mysql> select * from pet where species not in ('cat','bird');
//字符匹配查询
%通配符 代表任意多个字符
_单个字符
//H%表示查询以H开头的任意字符 也可以使用^
mysql> select * from pet where owner like 'h%';
//%y表示查询以y结尾任意字符串 也可以使用$
mysql> select * from pet where owner like '%y';
//%e%表示查询在任意位置包含字母e的所有字符串
mysql> select * from pet where owner like '%e%';
//_e%表示第二个字符为e的所有字符串
mysql> select * from pet where owner like '_e%';
//未知值:
//查询宠物的死亡日期为空的所有宠物
mysql> select * from pet where death is null;
//查询已经死亡的所有宠物
mysql> select * from pet where death is not null;
//作业:
1.查询出生日期在1990--1998之间宠物并且性别为f。
mysql> select * from pet where birth between '1990' and '1998' and sex='f';
2.查询宠物的种类是snake或者是dog所有宠物
mysql> select * from pet where species='dog' or species='snake';
3.查询种类是cat 并且sex=f 或种类 dog并且出生日期大于1990;
mysql> select * from pet where( species='cat' and sex='f') or (species='dog' and birth>'1990');
4.查询宠物的主人是:Gwen的所有宠物
mysql> select * from pet where owner='gwen';
5.查询宠物的主人是:Gwen并且种类是cat的所有宠物的记录
mysql> select * from pet where owner='gwen' and species='cat';
6.查询宠物的主人是:Gwen的或者种类是cat的所有宠物
mysql> select * from pet where owner='gwen' or species='cat';
7.查询宠物的出生日期大于1990并且宠物的种类是dog或者是cat的所有宠物的记录
mysql> select * from pet where birth>'1990' and( species='dog' or species='cat');
8.查询宠物的注入式Gwen或者是Harlod并且宠物的种类是dog并且性别是m的所有宠物的记录
mysql> select * from pet where (owner='gwen' or owner='harlod') and species='dog' and sex='m';
//Order by 子句 对结果集进行排序。
//排序有升序asc 默认的
//降序desc 两种
mysql> select name, birth from pet order by birth;
mysql> select name ,birth from pet order by birth desc;
mysql> select name,birth from pet where species='dog' order by birth;
//group by 子句
group by子句对某一列数据的值进行分类,形成结果集,然后在结果集的基础上进行分组。
mysql> select species from pet group by species;
//第一步执行:select species from pet;
//第二步执行:group by species;
group by子句通常与常用的函数 联合使用
count(*) //COUNT(*)它返回检索行的数目, 不论其是否包含 NULL值。
mysql> select count(*) from pet;
sum()
avg()
max()
//宠物中最大的年龄
mysql> select max(birth) from pet;
//宠物种类年龄最大的宠物种类
mysql> select species,max(birth) from pet group by species;
//宠物种类年龄最大的宠物名称,种类
mysql> select name,species,max(birth) from pet group by species;
min()
//作业宠物种类年龄最小 的宠物名称,种类,
abs
rand
round
//查询每一种宠物的个数
mysql> select species,count(*) as '总数' from pet group by species;
mysql> select species ,count(*) from pet group by species;
//having子句
having子句相当于一个用于组的where子句 ,它指定了组或聚合的搜索条件 。having子句通常与group by子句一起使用。
在使用having子句定义搜索条件时,它只有与组有关,而不是单个的数据有关 规则如下:
1、如果指定了group by 子句,则having子句的搜索条件将应用于group by子句创建的组。
案例:查询宠物种类的个数大于2 的所有宠物的种类
select count(*) as cnt from pet group by species having cnt>2;
2、如果指定了where子句 而没有指定 group by 子句,那么having子句的搜索条件将应用于where子句的数据结果集。
案例:在查询的结果中筛选 出生日期大于1990
select * from pet where species='dog' having birth>'1990';
理解:1、首先执行select * from pet where species='dog'
2、在结果集在查找出生日期大于1990
3、如果既没有指定where子句,又没有指定group by子句,那么having子句的搜索条件将应用于from子句的输出结果集。
案例:查询所有的宠物信息 并且 筛选出种类为dog的所有宠物
select * from pet having species='dog';
等价于:select * from pet where speices='dog'; //执行的过程一样吗?
group by 与having的综合案例:
mysql> select species ,count(*) as cnt from pet group by species; //分组查询的结果
+---------+-----+
| species | cnt |
+---------+-----+
| NULL | 2 |
| bird | 2 |
| cat | 2 |
| dog | 4 |
| snake | 1 |
+---------+-----+
5 rows in set (0.00 sec)
//having子句是在上面的结果集中进行筛选处理 种类为bird 或者是dog
mysql> select species ,count(*) as cnt from pet group by species having species in ('bird','dog');
+---------+-----+
| species | cnt |
+---------+-----+
| bird | 2 |
| dog | 4 |
+---------+-----+
2 rows in set (0.00 sec)
作业:
1.查询宠物名称不是以B做为开头的所有宠物
select * from pet where name not like 'B_%';
2.查询宠物的出生日期为08月的所有宠物
select * from pet where birth like '____-08%';
mysql> select * from pet where month(birth)='08';
3.查询所有宠物要求性别不能为空 按照owner排序,birth降序。
select *
from pet
where sex is not null
order by owner, birth desc;
4.查询宠物的名称 要求只显示宠物名称的前3个字符
select left(name, 3) name from pet;
5.查询宠物的名称以B作为开头 使用两种方式实现
select * from pet where left(name,1)='B';
6.查询宠物中年龄最大的宠物记录
select max(birth) from pet;
select * from pet where birth = (select max(birth) from pet);
7.查询宠物按照宠物的性别分组 分别显示宠物性别的总数
select sex, count(*) from pet group by sex;
8.查询宠物的种类,性别 按照性别,种类分组并求出总数 //按种类和性别组合的动物数量
select species, sex, count(*) from pet group by species, sex;
9.查询宠物的种类不属于dog,cat的所有宠物
select * from pet where species not in ('dog', 'cat');
10.查询宠物的主人 按照主人分组并且宠物的出生日期大与1990 并且 c>2
mysql> select owner,count(*) c from pet where birth>'1990' group by owner having c>2 order by c;
11.查询所有的宠物按照种类升序 出生日期降序
mysql> select * from pet order by species,birth desc;
12.查询宠物主人的名称及主人所养宠物的个数
mysql> select owner,count(*) from pet group by owner;
13.查询每种性别的宠物数量及性别类型 并按照数数量升序排列
mysql> select sex,count(*) cnt from pet group by sex order by cnt;
mysql> select sex,count(*) from pet group by sex order by count(*);
14.查询按种类和性别组合的宠物数量
mysql> select species,sex,count(*) from pet group by species,sex;
15.查询按种类和性别组合的宠物的数量并且要求宠物的种类只能是cat或者dog
mysql> select species,sex,count(*) from pet where species in ('dog','cat') group by species,sex;
16.查询性别不为空的宠物并按性别分组宠物的数量:
mysql> select sex,count(*) from pet where sex is not null group by sex;
//查询所有的数据 owner不重复的(也就说只出现一次) 怎么办? 解答: 没有重复也就是只出现一次所以可以按照以下查询
mysql> select name,owner,species,sex,birth,death,count(*) cnt from pet group by owner having cnt=1;
mysql> select * ,count(*) cnt from pet group by owner having cnt=1;
注意:以上当只有一条记录时,才有意义,否则没有任何意义。
SQL函数
两种1.单行函数
2、多行行数
字符函数:
大小写转换函数 lower 小写 upper 大写
字符处理函数:concat 联接 substr length POSITION LPAD|RPAD TRIM REPLACE
案例:
mysql> select lower('STRING') ;
mysql> select upper('string');
mysql> select concat('abc','bac');
mysql> select length('aaaaaa');
mysql> select substr('abcdef',1,3);
mysql> select left('abcdefg',3);
LPAD(str,len,padstr)
返回字符串 str, 其左边由字符串padstr 填补到len 字符长度。假如str 的长度大于len, 则返回值被缩短至 len 字符。
mysql> SELECT LPAD('hi',4,'??');
-> '??hi'
mysql> SELECT LPAD('hi',1,'??');
-> 'h'
RPAD(str,len,padstr)
返回字符串str, 其右边被字符串 padstr填补至len 字符长度。假如字符串str 的长度大于 len,则返回值被缩短到与 len 字符相同长度。
mysql> SELECT RPAD('hi',5,'?');
-> 'hi???'
mysql> SELECT RPAD('hi',1,'?');
-> 'h'
返回字符串 str ,其引导空格字符被删除。
mysql> SELECT LTRIM(' barbar');
-> 'barbar'
返回字符串str 以及所有被字符串to_str替代的字符串from_str 。
mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
-> 'WwWwWw.mysql.com'
返回字符串 str ,顺序和字符顺序相反。
mysql> SELECT REVERSE('abc');
-> 'cba'
RIGHT(str,len)
从字符串str 开始,返回最右len 字符。
mysql> SELECT RIGHT('foobarbar', 4);
-> 'rbar'
mysql> SELECT SUBSTRING('Quadratically',5);
-> 'ratically'
mysql> SELECT SUBSTRING('foobarbar' FROM 4);
-> 'barbar'
mysql> SELECT SUBSTRING('Quadratically',5,6);
-> 'ratica'
mysql> SELECT SUBSTRING('Sakila', -3);
-> 'ila'
mysql> SELECT SUBSTRING('Sakila', -5, 3);
-> 'aki'
mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2);
-> 'ki'
mysql> select ascii('abcccc');//返回第一个字符的ascii码值
数值函数:
1、算术操作符
mysql> select 3+5;
2、数学函数
abs 绝对值
ROUND: 4舍5入到指定的小数位
ROUND(45.926, 2) 45.93
TRUNCATE: 将值截断到指定的小数位
TRUNCATE(45.926, 2) 45.92
MOD: 返回相除后的余数
MOD(1600, 300) 100
pow(x,y);
pi();
日期与时间函数:
mysql> SELECT ADDDATE('1998-01-02', 31);
-> '1998-02-02'
CONVERT_TZ() 将时间日期值dt 从from_tz 给出的时区转到to_tz给出的时区,然后返回结果值。
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
-> '2004-01-01 13:00:00'
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
-> '2004-01-01 22:00:00'
CURDATE()
将当前日期按照'YYYY-MM-DD' 或YYYYMMDD 格式的值返回,具体格式根据函数用在字符串或是数字语境中而定。
mysql> SELECT CURDATE();
-> '1997-12-15'
mysql> SELECT CURDATE() + 0;
-> 19971215
CURTIME()
将当前时间以'HH:MM:SS'或 HHMMSS 的格式返回, 具体格式根据函数用在字符串或是数字语境中而定。
mysql> SELECT CURTIME();
-> '23:50:26'
mysql> SELECT CURTIME() + 0;
-> 235026
DATE(expr)
提取日期或时间日期表达式expr中的日期部分。
mysql> SELECT DATE('2003-12-31 01:02:03');
-> '2003-12-31'
DATEDIFF() 返回起始时间 expr和结束时间expr2之间的天数。Expr和expr2 为日期或 date-and-time 表达式。计算中只用到这些值的日期部分。
mysql> SELECT DATEDIFF('1997-12-31 23:59:59','1997-12-30');
-> 1
mysql> SELECT DATEDIFF('1997-11-30 23:59:59','1997-12-31');
-> -31
year()
time()
month()
day();
数据库的更新|删除
update更新数据
update 表名 set 更新列的值 where 更新条件
更新案例:
mysql> update pet set species='snake' where name='daben';
mysql> update pet set owner='army',death=now() where name='daben';
删除语句:
delete from 表名 where 删除条件;
删除案例:
mysql> delete from pet where name='nini';
3.3.4.9. 使用1个以上的表 参考
前面介绍的查询还局限在数据库的一张表内。但在实际应用中,我们经常需要在多张表中查询数据或者需要对表中的数据进行分类、汇总等。这就需要较为复杂的高级查询
pet表追踪你有哪个宠物。如果你想要记录其它相关信息,例如在他们一生中看兽医或何时后代出生,你需要另外的表。这张表应该像什么呢?需要:
· 它需要包含宠物名字以便你知道每个事件属于哪个动物。 name
· 需要一个日期以便你知道事件是什么时候发生的。 date
· 需要一个描述事件的字段。 remark
· 如果你想要对事件进行分类,则需要一个事件类型字段。 type
创建一个event表
宠物的名称:name varchar 20
事件发生的时间 date
事件的类型 type varchar15
事件的描述 remark varchar 200
创建此表
我们使用navicat创建
//order by group by having
1、多表查询
在设计数据库的时候,不可能只局限于一张表,我们需要设计很多张表,然后将数据分布到这些表中。将数据分布到多张表中的主要目的是为了存储数据更加方便。然而这些数据本来就是一个整体,所以我们在查询数据的时候,需要从这些表中将数据提取出来,重新聚合到一起显示给用户。
Mysql提供了实现多张表查询的方法----连接查询。所谓的连接查询时将多个表以某个或某些列为条件进行连接,从中检索出关联数据
多表查询的基础
基本规则: select 子句列表中,每个字段列前道药假上基表的名称 别名
from 子句 应该包括所有使用的基表
where 应该定义一个同等连接
select count(*) from pet; //11
select count(*) from event; //11
select * from event,pet;//pet中的每一条记录 都会对应event表中所有记录
select count(*) from event,pet;//11*11=121;
//查询宠物发生过事件详细信息
select * from pet,event where pet.name=event.name;
//查询宠物发生过litter事件的详细信息
select * from pet,event where pet.name=event.name and event.`type`='litter';
//查询宠物发生过事件 宠物名称 主人 发生事件的时间 类型
select pet.name,pet.owner,event.`type`,event.`date` from event,pet where event.name=pet.name;
//查询宠物发生过事件 宠物名称 主人 发生事件的时间 类型 要求按宠物发生事件的时间升序排列
select pet.name,pet.owner,event.`type`,event.`date` from pet,event where pet.name=event.name order by event.`date` asc
//查询宠物发生过事件 并且事件的总数大于等于二的宠物名称;
select name,count(*) as c from event group by event.name having c>=2;
//查询宠物发生过事件并且事件的总数大于等于二的宠物名称 宠物的主人 宠物性别 宠物的出生日期 死亡日期
select pet.name,pet.owner,pet.sex,pet.birth,pet.death,count(*) as c from pet,event where pet.name=event.name group by pet.name having c>=2;
//使用别名查询 查询宠物发生过事件并且事件的总数大于等于二的宠物名称 宠物的主人 宠物性别 宠物的出生日期 死亡日期
select p.name,p.owner,p.sex,p.birth,p.death,count(*) as c from pet p,event e where p.name=e.name group by p.name having c>=2;
连接查询的分类:
内连接:是比较常用的一种数据连接查询方式,它使用比较运算符进行多个基表间的数据的操作,并列出这些基表中与连接条件相匹配的所有数据行。
1、等值连接
2、非等值连接
3、自然连接
它是连接查询的默认连接方式。
内连接的语法格式是:
select select_list from table inner join table2 [on join_conditions] [where search_conditions][order by order_expression].....
1、等值连接
等值连接查询就是在连接条件中使用比较运算符等于号(=)来比较连接列的列值。其查询结果中列出被连接表中的所有列,并且包括重复列。
等值连接有两种表现方式:1、select * from pet,event where pet.name=event.name;
2、修改为内连接方式:
select * from pet inner join event on pet.name=event.name;
select * from pet p inner join event e where p.name=e.name;
//查询发生过事件的宠物的详细信息 并按照出生日期升序排列
select * from pet p inner join event e on p.name=e.name order by p.birth;
////查询发生过事件的宠物的 性别 并按照性别分组 及每组数量
select count(*) ,p.sex from pet p inner join event e on p.name=e.name group by p.sex;
////查询发生过事件的宠物的 性别 并按照性别分组 及每组数量大于2性别信息
select count(*) as c ,p.sex from pet p inner join event e on p.name=e.name group by p.sex having c>2;
2、非等值连接
非等值连接查询就是在连接条件中使用除了等于号之外的比较运算符,来比较连接的列的列值。在非等值连接中,可以使用的比较运算符有:> < >= <= <> 可以使用范围运算符between and 。
//查询发生过事件宠物的详细信息 并 要求出生日期大于>1997得所有宠物
select * from pet p inner join event e on p.name=e.name and p.birth>'1997';
3、自然连接
自然连接(Natural join)是一种特殊的等值连接,它要求两个关系中进行比较的分量必须是相同的属性组,并且在结果中把重复的属性列去掉。而等值连接并不去掉重复的属性列。 自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。。
比如 学生表 成绩表
sno sno
sname sname
sage ssbjut
sclass
select * from student inner join scroe on studnet.sno = scroe.sno
//自然连接
select s.*,sc.ssbjut from student s inner join scroe sc on s.sno=sc.sno;
//distinct //去除重复行 某个字段重复的行
//查询没有发生过任何事件的宠物的详细信息
内连接总结:
当至少有一个同属于两个表的行符合连接条件时,内连接才返回行。内连接可以消除与另一个表的任何行不匹配的行。
外连接:
外连接当至少有一个同属于两个表的行符合连接条件时,而外连接返回from子句中提到的至少一个表或试图表中的所有符合任何搜索条件的行。在外连接中参与连接的表有主从之分,主表中的每行数据去匹配从表中的数据行,如果符合连接条件,则直接返回到查询结果中;如果主表中的行在从表中没有找到匹配的行,在内连接中将丢弃比配的行,与内连接不同的是,在外连接中的主表的行仍然保留,并且返回到查询结果中,相应的从表中的行中被填上空值也返回到结果中。
外连接返回所有匹配的行和一定的不匹配的行。 这主要取决于建立外连接的类型:
1、左外连接:
外连接的语法格式:
select select_list from ltable left outer join rtable on [join_conditions]
总结:左外连接即在连接两个表时,不管右表中是否有匹配数据,结果将保留左表中的所有行
//左外连接
select * from pet left outer join event on pet.name=event.name;
//把上面左外连接 两个表 调换顺序 就和右外连接执行的结果一致
select * from event left outer join pet on pet.name=event.name;
2、右外连接
右连接的语法格式:
select select_list from ltalbe right outer join rtable on [join_conditions]
总结:右外连接即在连接两个表时,不管左表中是否有匹配数据,结果将保留右表中的所有行
//右外连接
select * from pet right outer join event on pet.name=event.name;
//右外连接 只是把连个表调换位置 就和左外连接执行的结果一致
select * from event right outer join pet on pet.name=event.name;
3、完全连接
完全连接的语法格式:
select select_list from ltable full outer join rtable on [join_conditions]
总结:整合1 2就是
Mysql不支持全连接 full join
联合查询:
联合查询解决:
union all //all 是个可选的关键字
Mysql中实现全连接的方式:
select * from pet p left outer join event e on p.name=e.name union select * from pet p right outer join event e on p.name=e.name ;
交叉连接
当对两个表使用交叉联接查询时,将生成来自这个两个表的各行的所有可能得组合。
语法格式是:
select select_list
from table1
cross join table2
where search_conditions
select * from pet cross join event;
select * from pet,event;
select * from pet cross join event on pet.name=event.name;
select * from pet ,event where pet.name=event.name;
以上的查询 都成为 单层查询
嵌套查询
所谓嵌套查询指的是在一个select查询内再嵌入一个select查询。外层的select语句叫外部查询,内层的select语句叫子查询。
使用子查询注意事项:
子查询可以嵌套多层
子查询需要圆括号()括起来
子查询中不能使用into子句
子查询中不能使用text数据类型
1、多行子查询
所谓多行子查询,是指执行查询语句获得的结果集中返回了多行数据的子查询。在子查询中可以使用in关键字和比较运算符来连接表。
1、in关键字的使用
//查询发生过事件的宠物信息
//分析:第一步在event表中查询出所有的宠物的名称 但是需要去掉重复name字段
select distinct name from event
//分析:第二步在第一步查询的结果集上完成下面的操作 //把第一个select语句查询的结果 作为第二步查询的条件。
select * from pet where name in (select distinct name from event);
//查询没有发生过任何事件的宠物信息
select * from pet where name not in (select distinct name from event);
2、使用比较运算符
//第一步查询event表中的名称为Fluffy的发生日期
select date from event where name='Fluffy';
//查询宠物的详细信息 要求宠物的出生日期 大于Fluffy的事件发生日期
select * from pet where birth>(select date from event where name='Fluffy');
索引:
索引是一单独的,物理的数据库结构,它是某个表中一列或者若干列的集合和相应指向表中物理标识这些值的数据页的逻辑指针清单。
索引是依赖于表建立的,它提供了在数据库中编排表中数据的内部方法。
一个表的存储是由两部分组成的:
一部分是用来存放表的数据页面。
一部分用来存放索引的页面。
MySQL有四种类型的索引:
主键、唯一索引、全文索引和普通索引。
主键:
业务主键 :
逻辑主键 :
表关系:
表之间有3种类型的关系:
一对多 //解决方案:是拿一端的主键作为 多端外键进行关联。
多对一
多对多
关联关系的解决:
创建仓库管理的数据库 名称:ordermsg
在此数据库中我们创建三张表: 库存表:Stores 订单表:Orders 客户表:Customers
库存表:
零件号:Pno char 6
零件名称:pname varchar 20
零件类别:ptype char 4
零件数量: pnum int
------业务主键 pno 作为表的主键
客户表:
客户编号: cno char 6
客户名称:cname varchar 20
客户电话:ctel varchar 12
客户住址:caddr varchar 100
客户邮编:czip varchar 6
------业务主键 cno 作为表的主键
订单表:
订单号: ono char 6
客户编号:cno char 6 //作为外键存在。 cno 的属性类型应于一端的类型 长度等必须一致。
零件号:pno char 6
订单数量:onum int
订单金额:osum double
订单日期: odate
作业
1. INSERT命令输入数据
使用Insert命令分别向OrderMsg数据库中的三个表中输入如下5条数据。
1) Stores(Pno, Pname, Ptype, Pnum)
库存(零件号,零件名称,零件类别,零件数量)
Pno Pname Ptype Pnum
P1 齿轮 传动 200
P2 蜗杆 传动 30
P3 螺栓 标准 120
P4 垫圈 标准 500
P5 螺母 标准 1020
2) Orders(Ono, Cno, Pno, Onum, Osum, Odate)
订单(订单号,顾客号,定购零件号,定购数量,订单金额,签订日期)
Ono Cno Pno Onum Osum Osum
O1 C2 P2 100 1000 200**-8
O2 C3 P3 10 100 2008-5-2
O3 C1 P2 20 200 2007-4-5
O4 C1 P4 2 20 2009-2-4
O5 C3 P5 1 10 2009-3-1
3) Customers(Cno, Cname, Ctel, Caddr, Czip)
顾客(顾客号,顾客名称,电话,地址,邮编)
Cno Cname Ctel Caddr Czip
C1 北京联合大学 010-64900310 北京 100101
C2 上海贝尔 021-23232323 上海
C3 LG 0755-2325123 深圳 412100
C4 华为(北京) 北京
C5 香港航空 852-56545236 香港 142553
2.把stores表中所有零件的数量增长一倍
3.把orders表中签订日期在2005年之前的数据删除。
4.向stores表中添加一列:零件颜色(Pcolour);
5.查询三个表中的内容
6.查询所有订单的金额,并按照金额的降序排列
7.查询签订日期在2009年的所有订单的信息。
8.查询顾客姓名中含有“北京”的顾客姓名和电话。
9.查询库存数量少于100的零件号和名称。
10.查询邮编为空的顾客的情况。
11.完成实验报告并回答问题
1) 使用Insert命令需要注意哪些问题
2)Alter与Update语句有什么区别
作业2:
查询订单金额大于100的顾客的名称和电话;
查询所有签订订单的顾客的名称和邮编;
统计每类零件的数量分别为多少;
统计每个顾客签订订单的次数;
查询所有顾客签订订单的情况(包括没有签订订单的顾客);
查询没有卖过一次的零件号(没有订单);
查询每个顾客签订订单的金额总数;
查询所有订单金额的平均值;
查询至少签订过两次订单的顾客信息。
完成实验报告并回答问题
1) 外连接与内联接的区别在哪里
2)使用子查询需要注意哪些事项