数据定义语言(DDL), 用于定义和管理对象,
例如数据库、数据表以及视图,
例如:CREATE、DROP、ALTER等语句。
数据操作语言(DML), 用于操作数据库对象所包含的数据,
例如:INSERT(插入)、UP-DATE(修改)、DELETE(删除)语句。
数据查询语言(DQL), 例如:SELECT语句。
数据控制语言(DCL), 用于控制对数据库对象操作的权限,
例如:GRANT、REVOKE、COMMIT、ROLLBACK等语句。
唯一约束:
name varchar(20) not nul unique
允许为空,但只能有一个空值,唯一约束可以确保一列或者多列不会出现重复值。
默认约束:
sex varchar(20) default "BAOML"
非空约束:
not null;
主键约束:
primary key;
主键自增:
AUTO_INCREMENT
使用DESC查看表结构查询顺序。
desc 表名;
修改数据表:
MYSQL 使用ALTER TABLE 语句修改表,
如修改表名、字段数据类型、字段名、增加删除字段、修改字段排序位置、增加删除约束等。
修改表名:---rename---
alter table oldTest rename newTest;
修改字段数据类型:---modify--- (注意:数值可以改字符,但字符不可以改为数值 (前提表里面存储的有对应的数据))
alter table 表名 modify 字段名 新数据类型 [约束];
例如:alter table 表名 modify age varchar(10) not null;
修改字段名和字段数据类型:---change---
alter table 表名 change 旧字段名 新字段名 新数据类型;
例如:alter table 表名 change id newId int(10);
添加字段:---add---
alter table 表名 add 新字段名 数据类型 [first | after]
例如:alter table 表名 add address varchar(30);
可选参数:---first | after---
FIRST 将新的字段设置顺序为第一个,
AFTER 指定在某个字段之后插入新字段。
例:alter table 表名 add weight float first;
alter table 表名 add height float after sex;
删除字段:---drop---
alter table 表名 drop 字段名;
例如:alter table 表名 drop weight;
修改字段排序位置:---modify---
例1:将字段1设置为第一个
alter table 表名 modify 字段1 数据类型 first;
例如:alter table 表名 modify username varchar(20) first;
例2:将字段1设置到字段2之后
alter table 表名 modify 字段1 数据类型 after 字段2;
例如:alter table 表名 modify username varchar(20) after sex;
更改表的储存引擎:
使用 SHOW ENGINES;查看系统支持的存储引擎。
格式:
alter table 表名 engine = 更改后的存储引擎名;
alter table 表名 engine memory;
修改约束:
删除外键约束:
alter table 表名 drop foreign key 约束;
例如:alter table 表名 drop foreign key stu_ibfk_1;
外键名是在设置外键时 CONSTRAINT 关键字之后的参数,
如果没有设置外键名,那么会有默认的外键名称,通过建表语句(show create table 表名;)查询。
新增外键约束:
alter table 表名 add [constrant 约束名] foreign key(外键列) reference 父表(父表主键名);
例如:alter table stu add foreign key(cid) references class(id);
删除主键约束:
alter table 表名 drop primary key;
例如:alter table stu drop primary key;
新增主键:
alter table 表名 add [constraint 约束名] primary key(主键名...);
例如:alter table stu add primary key(id);
添加唯一约束:
alter table 表名 add [constraint 约束名] unique(字段名);
例如:alter table yuangong add unique(username);
删除唯一约束:
alter table 表名 drop index 字段名;
例如:alter table yuangong drop index username;
设置默认约束:
alter table 表名 alter 字段 set default 默认值;
例如:alter table yuangong alter username set default "BAOMI";
删除默认值:
alter table 表名 alter 字段 drop default;
例如:alter table yuangong alter username drop default;
设置非空约束:
alter table 表名 modify 字段名 字段定义 not null;
需要注意的是,设置非空约束是,已经存在数据的字段是null值情况下是无法设置成功的。
删除数据表:
drop table 表名;
drop table 表名1,表名2...;
删除数据表,如果表不存在也可以执行,但是会发出警告
drop table if exists 表名;
增删改查:
增:insert into 表名 (字段1,字段2,...) values(值1,值2,...);
insert into 表名 values(值1,值2,值3);
insert into 表名 VALUES(值1,值2…), (值1,值2…), (值1,值2…);
将查询结果插入到表中:
INSERT [INTO] dest_table(字段名…) SELECT 字段名… FROM src_table [WHERE(条件)]
insert into student1 (id,name,sex) select id,name,sex from student;
注意:查询到的结果应与表1指定的字段列表的类型一致,
才可以将查询到的结果添加到表1中。
删:delete from 表名 where(条件);
如果没有条件删除所有数据。
delete from 表名 where id = 1;
删除该表内id等于1的一行
例如:删除address字段为null值的数据
delete from emp where address is null;
例如:delete from employees where last_name = "张" and first_name = "三";
例如:delete from employees where last_name in ("夏侯2","孙2");
删除多个;
改:update 表名 set 字段1 = '值',字段2 = '值' where(条件); 如果不指定where语句,则会修改所有。
例如:update 表名 set stu_name = '名字',age = 18;
同时修改该表内所有数据
例如:update 表名 set stu_name = '名字',age = 22 where id = 3;
修改该表内id = 3 的一行数据
查: select 字段1,字段2 from 表名;
查询表中指定字段的数据
select * from 表名;
查找该表内的所有内容
select * from 表名 where id > 2;
查账该表内id>2的所有数据;
删除外键约束:
1、查看数据库表创建的sql语句: show create table 表名;
2、查看外键的约束名:
CREATE TABLE `tb_1807_stu` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`stu_name` varchar(50) DEFAULT NULL,
`age` int(3) DEFAULT NULL,
`class_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `class_id` (`class_id`),
CONSTRAINT `tb_1807_stu_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class_1807` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
3、解除外键约束:
alter table 表名 drop foreign key tb_1807_stu_ibfk_1;
4、删除外键:
alter table 表名 class_id;
解除后的sql语句:
CREATE TABLE `tb_1807_stu` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`stu_name` varchar(50) DEFAULT NULL,
`age` int(3) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
新增外键约束:
1、格式:
alter table 表名 add foreign key (外键列) references 父表(父表主键名);
例如:alter table tb_1807_stu add foreign key(class_id1) references class_1807(id);
外键约束可以新增多个,但是约束的键的数据类型要和父表的主键数据类型保持一致。
sql建表语句:
CREATE TABLE `tb_1807_stu` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`stu_name` varchar(50) DEFAULT NULL,
`age` int(3) DEFAULT NULL,
`class_id` int(11) DEFAULT NULL,
`class_id1` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `class_id` (`class_id`),
KEY `class_id1` (`class_id1`),
CONSTRAINT `tb_1807_stu_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class_1807` (`id`),
CONSTRAINT `tb_1807_stu_ibfk_2` FOREIGN KEY (`class_id1`) REFERENCES `class_1807` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
删除外键关联时要注意的事项:
1、不能直接删除父表,因为直接删除父表,字表没有参照破坏了参照完整性。
2、如果需要删除父表,则应先解除字表与父表的外键约束或者删除子表所有内容,然后就可以删除父表。
外键约束:
案例1:
CONSTRAINT fk_pro_com FOREIGN KEY(cid) REFERENCES company(id)
约束 fk_pro_com 外键(外键列) 参考 父表名(父表主键)
CREATE TABLE company(
id INT(5) PRIMARY KEY,
name VARCHAR(20),
address VARCHAR(20),
ceo VARCHAR(10),
employees int(10)
);
CREATE TABLE product(
id INT(5) PRIMARY KEY,
name VARCHAR(20),
address VARCHAR(20),
unit VARCHAR(2),
pro_date DATE,
cid INT(5),
CONSTRAINT fk_pro_com FOREIGN KEY(cid) REFERENCES company(id)
);
案例2:
FOREIGN KEY(class_id) REFERENCES class(class_id)
外键(外键列) 参考 父表名(父表主键)
CREATE TABLE class(
class_id INT PRIMARY KEY,
class_teacher VARCHAR(20),
class_manager VARCHAR(20),
class_room VARCHAR(10)
);
CREATE TABLE stu(
stu_id INT PRIMARY KEY,
stu_name VARCHAR(20),
stu_age INT,
class_id INT,
FOREIGN KEY(class_id) REFERENCES class(class_id)
);
查询语句:
where 条件:
binary :区分大小写
and or in
+ - * / %
>= <= > < !=(not)
select 字段1,字段2 from 表名;
查询表中指定字段的数据
select * from 表名;
查找该表内的所有内容
select * from 表名 where id > 2;
查账该表内id>2的所有数据;
查询表中的数据并指定查询结果必须满足的条件:
select 字段1,字段2 from 表 where 条件;
使用AND 进行多条件查询:
select 字段1,字段2 from 表 where 条件1 and 条件2;
使用OR 进行多条件查询
select 字段1,字段2 from 表 where 条件1 or 条件2;
注意:AND 和OR运算符可以同时使用,但是AND运算符优先级要大于OR运算符。
使用 as 起别名:
格式:select 字段1 as 别名1, 字段2 as 别名2... from 表 [where(条件)];
例如:select name as Name from 表;
使用concat(str1,str2,...)和并查询字段
格式:select concat(字段1,字段2) as 新别名 from 表名 [where(条件)];
例如:select concat(last_name,first_name) as new_name from student [where(条件)];
字符串模糊查询,根据指定关键字进行模糊查询:
select 字段 from 表 where 某字段 like 条件
通配符的分类:
_:下划线通配符:表示只能匹配单个字符,不能多也不能少,就是一个字符.
%:百分号通配符: 表示任何字符出现任意次数(可以是0次).
1)_通配符使用:
select * from products where products.prod_name like '_yves';
匹配结果为: 像"yyves"这样记录.
select * from products where products.prod_name like 'yves__';
匹配结果为: 像"yveshe"这样的记录.(一个下划线只能匹配一个字符,不能多也不能少)
2)%通配符使用:
匹配以"yves"开头的记录:(包括记录"yves")
select * from products where products.prod_name like 'yves%';
匹配包含"yves"的记录(包括记录"yves")
select * from products where products.prod_name like '%yves%';
匹配以"yves"结尾的记录(包括记录"yves",不包括记录"yves ",也就是yves后面有空格的记录,这里需要注意)
select * from products where products.prod_name like '%yves';
去重查询: 将查询结果去除重复数据,使用DISTINCT语句
select distinct 字段名1,字段名2 … from 表;
注意:如果去重查询多个字段,是多个字段一样的记录才会被去重。
例如:select disinct name,sex,age from emp;
limit语句截取数据:注意:limit写在最后。
通过LIMIT语句截取查询语句中的指定条数的数据。
语法1:select * from 表名 limit n,m;
n : 从第几条截取,m : 截取的数目。
从n开始,公m条数据;
(n,m个]
语法2:select * from 表名 limit 2;
n:截取前n条数据(写几查询几个)
范围过滤:
between…and: (包含 闭区间)
select * from 表 where 字段 between 值1 and 值2;
排序:order by:
对查询结果进行排序
select 字段 from 表 order by 字段;
对查询结果进行多列排序
select 字段 from 表 order by 字段1,字段2;
执行结果为先按字段1排序,如果遇到字段1相同的数据则按字段2排序。
例如:name,age进行排序:
select * from emp order by name desc,age desc;
指定排序方向: 默认情况下,使用ORDER BY语句对查询结果进行排序,
数字按照大小、字母按照A~Z进行升序排序,
还可以通关键字DESC 实现降序排序。
升序排序:select 字段 from 表 order by 字段 asc;
降序排序:select 字段 from 表 order by 字段 desc;
例如:根据名字降序排序:
select * from emp order by name desc;
分组聚合
count()函数:计数
例如:select count(1|字段) as 别名 from 表名;
sum() : 求和函数
例如:select sum(字段) as 别名 from 表名;
max() : 求最大值
例如:select max(字段) as 别名 from 表名;
min() : 求最小值
例如:select min(字段) as 别名 from 表名;
avg() : 求平均值
例如:select ava(字段) as 别名 from 表名;
group by : 分组函数
例如:select name,sex,count(sex) as 别名 from 表名 group by sex;
把数据按照性别进行分组,性别有空的也会被分为一组
having : 条件过滤
例如:select name,sex as sex,count(sex) from student group by sex having count(sex);
select name,sex as sex from student having sex = '男';
表连接
表连接分为内连接和外连接。
他们之间最主要的区别:内连接仅选出两张表中互相匹配的记录,外连接会选出其他不匹配的记录。
以下是员工表staff和职位表deptno:
内连接
select staff.name,deptname from staff,deptno where staff.name=deptno.name;
外连接 分为左连接和右连接
左连接:包含所有左边表中的记录,甚至是右边表中没有和他匹配的记录。
右连接:包含所有右边表中的记录,甚至是右边表中没有和他匹配的记录。
外连接(左连接):
select staff.name,deptname from staff left join deptno on staff.name=deptno.name;
外连接(右连接):
select deptname,deptno.name from staff right join deptno on deptno.name=staff.name;
表连接
大类上分为外连接和内连接
外链接 又分为左连接和右连接
左连接:包含所以的左边表中的记录甚至是右边表中没有和它匹配的记录。
右连接:同上
select ename,detname from emp left join dept on emp.deptno=dept.deptno;
左连接和右连接可以相互转换
子查询
select * from emp where deptno in(select deptno from dept);
如果子查询记录唯一,可以使用=替代in
select * from emp where deptno =(select deptno from dept limit 1);
记录查询
将两个表的数据按照一定的查询出来后,将结果合在一起显示
union all 是将结果集合并在一起,而union是将union all后的结果在进行一次distinct,去除重复
select deptno from emp union all select deptno from dept;
select demtno from emp union select deptno from dept;
表的别名
可以使用别名为表添加不同的名称。使用AS关键字在表名称分配别名,如下查询语句语法:
table_name AS table_alias
两个表都具有相同的列名称:customerNumber。如果不使用表别名来指定是哪个表中的customerNumber列:
select customername, count(o.ordernumber) total from customers c
inner join orders o on c.customernumber = o.customernumber
group by customername having total >=5 order by total desc;
二:INNER JOIN内连接
1.介绍
INNER JOIN子句将一个表中的行与其他表中的行进行匹配,并允许从两个表中查询包含列的行记录。
INNER JOIN子句是SELECT语句的可选部分,它出现在FROM子句之后。
在使用INNER JOIN子句之前,必须指定以下条件:
首先,在FROM子句中指定主表。
其次,表中要连接的主表应该出现在INNER JOIN子句中。理论上说,可以连接多个其他表。 但是,为了获得更好的性能,应该限制要连接的表的数量(最好不要超过三个表)。
第三,连接条件或连接谓词。连接条件出现在INNER JOIN子句的ON关键字之后。连接条件是将主表中的行与其他表中的行进行匹配的规则。
使用语法:
select column_list from t1
inner join t2 on join_condition1
inner join t3 on join_condition2
...
where where_conditions;
原理:
对于t1表中的每一行,INNER JOIN子句将它与t2表的每一行进行比较,以检查它们是否都满足连接条件。
当满足连接条件时,INNER JOIN将返回由t1和t2表中的列组成的新行。
2.避免列的问题
如果连接具有相同列名称的多个表,则必须使用表限定符引用SELECT和ON子句的列,以避免列错误。
例如,如果t1和t2表都具有名为c的一个相同列名,则必须在SELECT和ON子句中使用表限定符,如使用t1.c或t2.c指定引用是那个表中的c列。
3.两种相同的做法
语句返回相同的结果集,但是使用此语法,不必使用表的别名
select
productCode,
productName,
textDescription
from
products t1
inner join
productlines t2 on t1.productline = t2.productline;
------------------------
select
productCode,
productName,
textDescription
from
products
inner join
productlines using (productline);
4.GROUP BY子句
select
T1.orderNumber,
status,
summ(quantityOrdered * priceEach) total
from
order as T1
inner join
orderdetails as T2 on T1.orderNumber = T2.orderNumber
group by orderNumber;
----------------
相同的结果:
select
orderNumber,
status,
sum(quantityOrdered * priceEach) total
from
orders
inner join
orderdetails using (orderNumber)
group by orderNumber;
5.使用=以外的运符
也可以使用大于(>),小于(<)和不等于(<>)运算符的其他运算符来形成连接谓词。
以下查询使用少于(<)连接来查找低于代码为S10_1678的产品的销售价格的制造商建议零售价(MSRP)的所有产品。
select
ordernumber,
productName,
msrp,
priceEach
from
products padstr
inner join
orderdetails o on p.productcode = o.productcode
and p.msrp > o.priceEach
where
p.productcode = 'S10_1678';
三:MySQL左连接(LEFT JOIN)
1.简介
LEFT JOIN子句允许您从匹配的左右表中查询选择行记录,
连接左表(t1)中的所有行,
即使在右表(t2)中找不到匹配的行也显示出来,但使用NULL值代替。
https://images2017.cnblogs.com/blog/1027015/201711/1027015-20171121223737930-992413488.png
2.示例
select
c.customerNumber,
customerName,
orderNumber,
status
from
customers cast
left join orders using (customerNumber);
3.使用MySQL LEFT JOIN子句来查找不匹配的行
select
c.customerNumber,
customerName,
orderNumber,
status
from
customers c
left join
orders o on c.customerNumber = o.customerNumber
where orderNumber is null;
五:自连接
1.介绍
在同一张表上自己连接自己。
当您想将表中行与同一表中的其他行组合时,可以使用自连接。要执行自联接操作必须使用表别名来帮助MySQL在单个查询中区分左表与同一张表的右表。
2.要获得整个组织结构
以使用employeeNumber和reportsTo列将employees表连接自身。
employees表有两个角色:一个是经理,另一个是直接报告者(即,下属员工)。
select
concat(m.lastname, ', ', m.firstname) as 'Manager',
concat(e.lastname, ', ', e.firstname) as 'Direct report'
from
employees e
inner join
employees m on m.employeeNumber = e.reportsto
order by manager;
mysql中字符串的用法:
1、从左开始截取字符串 :
left(srt, length)
说明:left(被截取字段, 截取长度)
例如:select left (content,200) as '别名' from 表名;
2、 从右开始截取字符串 :
right(str, length)
说明:right(被截取字符串, 截取长度)
例如:select right (content,200) as '别名' from 表名;
3、截取字符串:
substring(str, pos)
说明:substring(被截取字段, 从第几位开始截取)
例如:select substring (content, 5) as '别名' from 表名;
substring(str, pos, length)
说明:substring(被截取字段, 从第几位开始, 截取长度)
例如:select substring(content, 5, 200) as '别名' from 表名;
(注:如果位数是负数,如 -5 则是从后倒数位数,到字符串结束或截取的长度)
sbustr(str,pos);
就是从pos开始的位置,一直截取到最后。
substr(str,pos,len);
这种表示的意思是,就是从pos开始的位置,截取len个字符(空白也算字符)。
需要注意的是:如果pos为1(而不是0),表示从第一个位置开始。
这点也很好理解,因为数据库不是我们平时写程序,他有他自己的一套习惯,数据库的记录都是从1开始没有从0开始。
4、按关键字截取字符串:(返回第count个分隔符左侧的内容)
substring_index (srt, delim, count)
说明:substring_index (被截取的字段, 关键字, 关键字出现的次数)
例如:select substring_index ("www.baidu.com", '.', 2) as 别名 from 表名;
结果:www.baidu
(注:如果关键字出现的次数是负数 如 -2 则是从后倒数,到字符串结束)
5、合并字符串:
concat(str1, str2, ...)
说明:concat(字段1, 字段2, ...)
返回结果为连接参数产生的字符串。如有任何一个参数为null,则返回值为null;
注意:
如果所有参数均为非二进制字符串,则结果为非二进制字符串。
如果自变量中含有任一二进制字符串,则结果为一个二进制字符串。
一个数字参数被转化为与之相等的二进制字符串格式;
若要避免这种情况,可使用显式类型 cast, 例如:
select concat(cast(int_col as char), char_col)
concat_ws(Separator, str1, str2, ...)
说明:concat_ws('分隔符', 字段1, 字段2)
concat_ws() 代表 Concat Witch Separator, 是concat()的特殊形式。
每一个参数是其他数的分隔符。分隔符的位置放在要连接的两个字符串 之间。
分隔符可以是一个字符串,也可以是其他参数。
注意:如果分隔符为null,则结果为null。函数会忽略任何分隔符参数后的null值。
和concat函数不同的是,concat_ws函数在执行的时候不会因为值为null而返回null。
6、合并为一行数据
group_concat : 把数据作为一行输出,用逗号分隔
[] 表示可填可不填
说明:group_concat( [DISTINCT] 要连接的字段 [Order BY 排序字段 ASC/DESC] [Separator '分隔符'] )
例如:
以id分组,把去除重复冗余的price字段的值打印在一行,逗号分隔
select id,group_concat(distinct price) from goods group by id;
7、复制字符串:
repeat()函数
格式:repeat('字符', 要复制的份数);
如果count <= 0,返回一个空字符串。如果str或count是NULL,返回NULL。
例如: 用来复制字符串,如下'ab'表示要复制的字符串,2表示要复制的份数;
select repeat('ab', 2); 结果 abab
8、locate 函数:
locate(substr, str)
返回子串 substr 在字符串 str 中第一次出现的位置。如果子串 substr 在 str 中不存在,
返回值为 0。如果 substr 或 str 为 null,则结果返回 null (从1开始)。
例如:select locate('bar', 'foobarbar'); -- >4
select locate('xbar', 'foobar'); -- > 0
locate(substr, pos)
返回子串 substr 在字符串 str 中的第 pos 位置后第一次出现的位置。如果 substr 不在
str 中放回 0 。如果 substr 或 str 为 null, 则返回 null。
例如:select locate('bar', 'foobarbar', 5);
position 函数:
position(substr in str) 等价于 locate(substr, str) (两者用法完全一样)
instr 函数:
instr(str, substr)
返回字符串 str 中第一次出现子字符串 substr 的位置。这与locate()的双参数形式相同,
只是参数的顺序相反。
示例:
SELECT position('a' IN 'banana'); # 2
SELECT locate('a', 'banana'); # 2
SELECT locate('a', 'banana', 3); # 4
SELECT locate('x', 'banana'); # 0
SELECT locate(1, 'banana'); # 0
SELECT locate(NULL , 'banana'); # null
SELECT locate('a' , NULL ); # null
SELECT instr('banana', 'a'); # 2
SELECT instr('banana', 'e'); # 0
lpad():
返回字符串str,左面用字符串 padstr 填补直到 str 是 len 个字符长。
lpad(str, len, padstr)
例如:select lpad('123', 10, '456'); -- > 4564564123
9、ascii ()
ascii(str)
返回字符串 str 最左边字符的 ascii 码值,如果是空字符串,则返回0,如果是 null,
则返回 null。输入时整形,也当做字符串处理。、
例如:select ascii('2'); -- > 50
select ascii(2); -- > 50
10、length():
计算字符串长度
length(str);
例如:select length('user'); -- > 12
11、
ltrim():
返回删除了其前置空格字符的字符串 str。
ltrim(str)
例如:select ltrim(' 121'); -- > 121
rtrim():
返回删除了其拖后空格字符的字符串 str。
trtim(str)
例如:select rtrim('121 '); -- > 121
trim()
返回字符串 str,其所有remstr前缀或后缀被删除了。
如果没有修饰符both、leading或trailing给出,both被假定。
如果remstr没被指定,空格被删除。
trim([[both | leading | trailing] [remstr] from] str);
例如:select trim(' dsf '); -- > dsf
select trim(leading 'x' from 'xxxbarxxx'); -- > barxxx;
select trim(trailing 'x' from 'xxxbarxxx'); -- > xxxbar;
12、ucase():
返回字符串 str,根据当前字符集映射(缺省是ISO-8859-1 Latin1)把所有的字符改变成大写。
该函数对多字节是可靠的。
ucase(str)
例如:select ucase('sae'); -- >SAE
13、lcase()
返回字符串 str,根据当前字符集映射(缺省是ISO-8859-1 Latin1)把所有的字符该边成小写。
该函数对多字节是可靠的。
lcase(str)
例如:select lcase('sS'); -- > ss
14、make_set():
返回一个集合(包含由 "," 字符分隔的子串组成的一个字符串),
由相应的位 bits 集合中的字符串组成。
str1 对应位 0 ,str2 对应位 1 ,等等。
在str1, str2, ... 中的 null 串 不添加到结果中。
make_set(bits, str1, str2, ...)
例如:select make_set(1 | 2, user,pass) from ctf;
+-------------------------+
| MAKE_SET(1|2,user,pass) |
+-------------------------+
| 1admin,11 |
| 4admin
,pass |
| admin123,123 |
| admin,test
|
+-------------------------+
15、reverse()
返回颠倒字符顺序的字符串 str
reverse(srt)
例如:select reverse('123'); -- > 321
16、space()
返回由N个空格字符组成的一个字符串
space(N)
例如:select concat(1, space(2), 3); -- > 1 3;
17、soundex():
返回 str 的一个同音字符串。听起来“大致相同”的2个字符串应该有相同的同音字符串。
一个“标准”的同音字符串长是4个字符,但是soundex()函数返回一个任意长的字符串。
你可以在结果上使用substring()得到一个“标准”的同音串。所有非数字字母字符在给定的字符串中被忽略。
所有在A-Z之外的字符国际字母被当作元音。
soundex(str)
例如:select soundex('hello'); -- > H400;
18、replace():
返回字符串 str ,其字符串from_str的所有出现有字符串to_str代替
replace(str, from_str, to_str);
例如:select replace('www.ok.com', 'w', 'q'); -- > qqq.ok.com
19、insert():
返回字符串 str ,在位置 pos 起始的子串且 len 个字符长的子串有字符串 newstr代替
insert(str, pos, len, newstr);
例如:select insert('dsfhdsa', 3, 4, 'ww'); -- > dswwa;
20、elt():
如果 n = 1, 返回str1,如果n = 2, 返回str2,等待。
如果 n 小于或大于 参数个数,返回null。elt() 是field() 反运算
elt(n, str1, str2, str3, ...);
例如:select elt(1, user(), version()); -- > root@localhost;
select elt(2, user(), version()); -- > 5.5.47;
21、field():
返回 str 在 str1, str2, str3 ...清单的索引。
如果str没找到,返回 0。field()是elt()反运算
field(str, str1, str2, str3, ...);
例如:select field('v', 'he', 'hekl'); -- > 0;
22、mid():
根据起始位置和长度返回相应的子字符串,与substring一样的用法
mid(ColumnName, Start [,length]);
例如:select mid('sfsdf', 2, 1); -- > f;
select mid('sfsdf', 2); -- >fsdf;
23、
length: 是计算字段的长度一个汉字是算三个字符,一个数字或字母算一个字符
char_length(str) 返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。对于一个包含五个二字节字符集, length()返回值为 10,而char_length()的返回值为5。
character_length(str) character_length()是char_length()的同义词。
bit_length(str) 返回2进制长度.
例如:可以查出用户名长度少于6个字符的用户列表。
sql
复制代码 代码如下:
select * from admin where length(username) < 6
char_length(str)
返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。对于一个包含五个二字节字符集, length()返回值为 10,而char_length()的返回值为5。
character_length(str)
character_length()是char_length()的同义词。
bit_length(str)
返回2进制长度.
简单的总结来说,mysql中获取字符串长度的有两个函数:
length:返回字符串所占的字节数,是计算字段的长度一个汉字是算三个字符,一个数字或字母算一个字符
char_length:返回字符串所占的字符数,不管汉字还是数字或者是字母都算是一个字符
24、find_in_set(str,strlist)
str 要查询的字符串
strlist 字段名 参数以”,”分隔 如 (1,2,6,8)
查询字段(strlist)中包含(str)的结果,返回结果为null或记录
假如字符串str在由N个子链组成的字符串列表strlist 中,
则返回值的范围在 1 到 N 之间。
一个字符串列表就是一个由一些被 ‘,’ 符号分开的子链组成的字符串。
如果第一个参数是一个常数字符串,而第二个是type SET列,
则FIND_IN_SET() 函数被优化,使用比特计算。
如果str不在strlist 或strlist 为空字符串,则返回值为 0 。
如任意一个参数为NULL,则返回值为 NULL。
这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行。
例子:
mysql> SELECT FIND_IN_SET('b', 'a,b,c,d');
-> 2 因为b 在strlist集合中放在2的位置 从1开始
select FIND_IN_SET('1', '1'); 返回 就是1 这时候的strlist集合有点特殊 只有一个字符串 其实就是要求前一个字符串 一定要在后一个字符串集合中才返回大于0的数
select FIND_IN_SET('2', '1,2'); 返回2
select FIND_IN_SET('6', '1'); 返回0
mysql时间:
一、MySQL 获得当前日期时间 函数
1.1 获得当前日期+时间(date + time)
函数:now()
例如:mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2008-08-08 22:20:46 |
+---------------------+
除了 now() 函数能获得当前的日期时间外,MySQL 中还有下面的函数:
current_timestamp()
,current_timestamp
,localtime()
,localtime
,localtimestamp -- (v4.0.6)
,localtimestamp() -- (v4.0.6)
这些日期时间函数,都等同于 now()。
鉴于 now() 函数简短易记,建议总是使用 now() 来替代上面列出的函数。
1.2 获得当前日期+时间(date + time)
函数:sysdate()
sysdate() 日期时间函数跟 now() 类似,
不同之处在于:now() 在执行开始时值就得到了,
sysdate() 在函数执行时动态得到值。看下面的例子就明白了:
mysql> select now(), sleep(3), now();
+---------------------+----------+---------------------+
| now() | sleep(3) | now() |
+---------------------+----------+---------------------+
| 2008-08-08 22:28:21 | 0 | 2008-08-08 22:28:21 |
+---------------------+----------+---------------------+
mysql> select sysdate(), sleep(3), sysdate();
+---------------------+----------+---------------------+
| sysdate() | sleep(3) | sysdate() |
+---------------------+----------+---------------------+
| 2008-08-08 22:28:41 | 0 | 2008-08-08 22:28:44 |
+---------------------+----------+---------------------+
可以看到,虽然中途 sleep 3 秒,但 now() 函数两次的时间值是相同的;
sysdate() 函数两次得到的时间值相差 3 秒。
MySQL Manual 中是这样描述 sysdate() 的:
Return the time at which the function executes。
sysdate() 日期时间函数,一般情况下很少用到。
2. 获得当前日期(date)
函数:curdate()
mysql> select curdate();
+------------+
| curdate() |
+------------+
| 2008-08-08 |
+------------+
其中,下面的两个日期函数等同于 curdate():
current_date()
,current_date
3. 获得当前时间(time)
函数:curtime()
mysql> select curtime();
+-----------+
| curtime() |
+-----------+
| 22:41:30 |
+-----------+
其中,下面的两个时间函数等同于 curtime():
current_time()
,current_time
4. 获得当前 UTC 日期时间函数:utc_date(), utc_time(), utc_timestamp()
mysql> select utc_timestamp(), utc_date(), utc_time(), now()
+---------------------+------------+------------+---------------------+
| utc_timestamp() | utc_date() | utc_time() | now() |
+---------------------+------------+------------+---------------------+
| 2008-08-08 14:47:11 | 2008-08-08 | 14:47:11 | 2008-08-08 22:47:11 |
+---------------------+------------+------------+---------------------+
因为我国位于东八时区,所以本地时间 = UTC 时间 + 8 小时。UTC 时间在业务涉及多个国家和地区的时候,非常有用。
二、MySQL 日期时间 Extract(选取) 函数。
1. 选取日期时间的各个部分:日期、时间、年、季度、月、日、小时、分钟、秒、微秒
set @dt = '2008-09-10 07:15:30.123456';
select date(@dt); -- 2008-09-10
select time(@dt); -- 07:15:30.123456
select year(@dt); -- 2008
select quarter(@dt); -- 3
select month(@dt); -- 9
select week(@dt); -- 36
select day(@dt); -- 10
select hour(@dt); -- 7
select minute(@dt); -- 15
select second(@dt); -- 30
select microsecond(@dt); -- 123456
2. MySQL Extract() 函数,可以上面实现类似的功能:
set @dt = '2008-09-10 07:15:30.123456';
select extract(year from @dt); -- 2008
select extract(quarter from @dt); -- 3
select extract(month from @dt); -- 9
select extract(week from @dt); -- 36
select extract(day from @dt); -- 10
select extract(hour from @dt); -- 7
select extract(minute from @dt); -- 15
select extract(second from @dt); -- 30
select extract(microsecond from @dt); -- 123456
select extract(year_month from @dt); -- 200809
select extract(day_hour from @dt); -- 1007
select extract(day_minute from @dt); -- 100715
select extract(day_second from @dt); -- 10071530
select extract(day_microsecond from @dt); -- 10071530123456
select extract(hour_minute from @dt); -- 715
select extract(hour_second from @dt); -- 71530
select extract(hour_microsecond from @dt); -- 71530123456
select extract(minute_second from @dt); -- 1530
select extract(minute_microsecond from @dt); -- 1530123456
select extract(second_microsecond from @dt); -- 30123456
MySQL Extract() 函数除了没有date(),time() 的功能外,其他功能一应具全。并且还具有选取‘day_microsecond’ 等功能。注意这里不是只选取 day 和 microsecond,而是从日期的 day 部分一直选取到 microsecond 部分。够强悍的吧!
MySQL Extract() 函数唯一不好的地方在于:你需要多敲几次键盘。
3. MySQL dayof...
函数:dayofweek(), dayofmonth(), dayofyear()
分别返回日期参数,在一周、一月、一年中的位置。
set @dt = '2008-08-08';
select dayofweek(@dt); -- 6
select dayofmonth(@dt); -- 8
select dayofyear(@dt); -- 221
日期 '2008-08-08' 是一周中的第 6 天(1 = Sunday, 2 = Monday, ..., 7 = Saturday);一月中的第 8 天;一年中的第 221 天。
4. MySQL week... 、
函数:week(), weekofyear(), dayofweek(), weekday(), yearweek()
set @dt = '2008-08-08';
select week(@dt); -- 31
select week(@dt,3); -- 32
select weekofyear(@dt); -- 32
select dayofweek(@dt); -- 6
select weekday(@dt); -- 4
select yearweek(@dt); -- 200831
MySQL week() 函数,可以有两个参数,具体可看手册。 weekofyear() 和 week() 一样,都是计算“某天”是位于一年中的第几周。 weekofyear(@dt) 等价于 week(@dt,3)。
MySQL weekday() 函数和 dayofweek() 类似,都是返回“某天”在一周中的位置。不同点在于参考的标准, weekday:(0 = Monday, 1 = Tuesday, ..., 6 = Sunday); dayofweek:(1 = Sunday, 2 = Monday, ..., 7 = Saturday)
MySQL yearweek() 函数,返回 year(2008) + week 位置(31)。
5. 返回星期和月份名称函数:dayname(), monthname()、
set @dt = '2008-08-08';
select dayname(@dt); -- Friday
select monthname(@dt); -- August
思考,如何返回中文的名称呢?
6. MySQL last_day() 函数:返回月份中的最后一天。
select last_day('2008-02-01'); -- 2008-02-29
select last_day('2008-08-08'); -- 2008-08-31
MySQL last_day() 函数非常有用,比如我想得到当前月份中有多少天,可以这样来计算:
mysql> select now(), day(last_day(now())) as days;
+---------------------+------+
| now() | days |
+---------------------+------+
| 2008-08-09 11:45:45 | 31 |
+---------------------+------+
三、MySQL 日期时间计算函数
1. MySQL 为日期增加一个时间间隔:date_add()
set @dt = now();
select date_add(@dt, interval 1 day); -- add 1 day
select date_add(@dt, interval 1 hour); -- add 1 hour
select date_add(@dt, interval 1 minute); -- ...
select date_add(@dt, interval 1 second);
select date_add(@dt, interval 1 microsecond);
select date_add(@dt, interval 1 week);
select date_add(@dt, interval 1 month);
select date_add(@dt, interval 1 quarter);
select date_add(@dt, interval 1 year);
select date_add(@dt, interval -1 day); -- sub 1 day
MySQL adddate(), addtime()函数,可以用 date_add() 来替代。下面是 date_add() 实现 addtime() 功能示例:
mysql> set @dt = '2008-08-09 12:12:33';
mysql>
mysql> select date_add(@dt, interval '01:15:30' hour_second);
+------------------------------------------------+
| date_add(@dt, interval '01:15:30' hour_second) |
+------------------------------------------------+
| 2008-08-09 13:28:03 |
+------------------------------------------------+
mysql> select date_add(@dt, interval '1 01:15:30' day_second);
+-------------------------------------------------+
| date_add(@dt, interval '1 01:15:30' day_second) |
+-------------------------------------------------+
| 2008-08-10 13:28:03 |
+-------------------------------------------------+
date_add() 函数,分别为 @dt 增加了“1小时 15分 30秒” 和 “1天 1小时 15分 30秒”。建议:总是使用 date_add() 日期时间函数来替代 adddate(), addtime()。
2. MySQL 为日期减去一个时间间隔:date_sub()
mysql> select date_sub('1998-01-01 00:00:00', interval '1 1:1:1' day_second);
+----------------------------------------------------------------+
| date_sub('1998-01-01 00:00:00', interval '1 1:1:1' day_second) |
+----------------------------------------------------------------+
| 1997-12-30 22:58:59 |
+----------------------------------------------------------------+
MySQL date_sub() 日期时间函数 和 date_add() 用法一致,不再赘述。另外,MySQL 中还有两个函数 subdate(), subtime(),建议,用 date_sub() 来替代。
3. MySQL 另类日期函数:period_add(P,N), period_diff(P1,P2)
函数参数“P” 的格式为“YYYYMM” 或者 “YYMM”,第二个参数“N” 表示增加或减去 N month(月)。
MySQL period_add(P,N):日期加/减去N月。
mysql> select period_add(200808,2), period_add(20080808,-2)
+----------------------+-------------------------+
| period_add(200808,2) | period_add(20080808,-2) |
+----------------------+-------------------------+
| 200810 | 20080806 |
+----------------------+-------------------------+
MySQL period_diff(P1,P2):日期 P1-P2,返回 N 个月。
mysql> select period_diff(200808, 200801);
+-----------------------------+
| period_diff(200808, 200801) |
+-----------------------------+
| 7 |
+-----------------------------+
在 MySQL 中,这两个日期函数,一般情况下很少用到。
4. MySQL 日期、时间相减函数:datediff(date1,date2), timediff(time1,time2)
MySQL datediff(date1,date2):两个日期相减 date1 - date2,返回天数。
select datediff('2008-08-08', '2008-08-01'); -- 7
select datediff('2008-08-01', '2008-08-08'); -- -7
MySQL timediff(time1,time2):两个日期相减 time1 - time2,返回 time 差值。
select timediff('2008-08-08 08:08:08', '2008-08-08 00:00:00'); -- 08:08:08
select timediff('08:08:08', '00:00:00'); -- 08:08:08
注意:timediff(time1,time2) 函数的两个参数类型必须相同。
四、MySQL 日期转换函数、时间转换函数
1. MySQL (时间、秒)转换函数:time_to_sec(time), sec_to_time(seconds)
select time_to_sec('01:00:05'); -- 3605
select sec_to_time(3605); -- '01:00:05'
2. MySQL (日期、天数)转换函数:to_days(date), from_days(days)
select to_days('0000-00-00'); -- 0
select to_days('2008-08-08'); -- 733627
select from_days(0); -- '0000-00-00'
select from_days(733627); -- '2008-08-08'
3. MySQL Str to Date (字符串转换为日期)函数:str_to_date(str, format)
select str_to_date('08/09/2008', '%m/%d/%Y'); -- 2008-08-09
select str_to_date('08/09/08' , '%m/%d/%y'); -- 2008-08-09
select str_to_date('08.09.2008', '%m.%d.%Y'); -- 2008-08-09
select str_to_date('08:09:30', '%h:%i:%s'); -- 08:09:30
select str_to_date('08.09.2008 08:09:30', '%m.%d.%Y %h:%i:%s'); -- 2008-08-09 08:09:30
可以看到,str_to_date(str,format) 转换函数,可以把一些杂乱无章的字符串转换为日期格式。另外,它也可以转换为时间。“format” 可以参看 MySQL 手册。
4. MySQL Date/Time to Str(日期/时间转换为字符串)函数:date_format(date,format), time_format(time,format)
mysql> select date_format('2008-08-08 22:23:00', '%W %M %Y');
+------------------------------------------------+
| date_format('2008-08-08 22:23:00', '%W %M %Y') |
+------------------------------------------------+
| Friday August 2008 |
+------------------------------------------------+
mysql> select date_format('2008-08-08 22:23:01', '%Y%m%d%H%i%s');
+----------------------------------------------------+
| date_format('2008-08-08 22:23:01', '%Y%m%d%H%i%s') |
+----------------------------------------------------+
| 20080808222301 |
+----------------------------------------------------+
mysql> select time_format('22:23:01', '%H.%i.%s');
+-------------------------------------+
| time_format('22:23:01', '%H.%i.%s') |
+-------------------------------------+
| 22.23.01 |
+-------------------------------------+
MySQL 日期、时间转换函数:date_format(date,format), time_format(time,format) 能够把一个日期/时间转换成各种各样的字符串格式。它是 str_to_date(str,format) 函数的 一个逆转换。
5. MySQL 获得国家地区时间格式函数:get_format()
MySQL get_format() 语法:
get_format(date|time|datetime, 'eur'|'usa'|'jis'|'iso'|'internal'
MySQL get_format() 用法的全部示例:
select get_format(date,'usa') ; -- '%m.%d.%Y'
select get_format(date,'jis') ; -- '%Y-%m-%d'
select get_format(date,'iso') ; -- '%Y-%m-%d'
select get_format(date,'eur') ; -- '%d.%m.%Y'
select get_format(date,'internal') ; -- '%Y%m%d'
select get_format(datetime,'usa') ; -- '%Y-%m-%d %H.%i.%s'
select get_format(datetime,'jis') ; -- '%Y-%m-%d %H:%i:%s'
select get_format(datetime,'iso') ; -- '%Y-%m-%d %H:%i:%s'
select get_format(datetime,'eur') ; -- '%Y-%m-%d %H.%i.%s'
select get_format(datetime,'internal') ; -- '%Y%m%d%H%i%s'
select get_format(time,'usa') ; -- '%h:%i:%s %p'
select get_format(time,'jis') ; -- '%H:%i:%s'
select get_format(time,'iso') ; -- '%H:%i:%s'
select get_format(time,'eur') ; -- '%H.%i.%s'
select get_format(time,'internal') ; -- '%H%i%s'
MySQL get_format() 函数在实际中用到机会的比较少。
6. MySQL 拼凑日期、时间函数:makdedate(year,dayofyear), maketime(hour,minute,second)
select makedate(2001,31); -- '2001-01-31'
select makedate(2001,32); -- '2001-02-01'
select maketime(12,15,30); -- '12:15:30'
五、MySQL 时间戳(Timestamp)函数
1. MySQL 获得当前时间戳函数:current_timestamp, current_timestamp()
mysql> select current_timestamp, current_timestamp();
+---------------------+---------------------+
| current_timestamp | current_timestamp() |
+---------------------+---------------------+
| 2008-08-09 23:22:24 | 2008-08-09 23:22:24 |
+---------------------+---------------------+
2. MySQL (Unix 时间戳、日期)转换函数:
unix_timestamp(),
unix_timestamp(date),
from_unixtime(unix_timestamp),
from_unixtime(unix_timestamp,format)
下面是示例:
select unix_timestamp(); -- 1218290027
select unix_timestamp('2008-08-08'); -- 1218124800
select unix_timestamp('2008-08-08 12:30:00'); -- 1218169800
select from_unixtime(1218290027); -- '2008-08-09 21:53:47'
select from_unixtime(1218124800); -- '2008-08-08 00:00:00'
select from_unixtime(1218169800); -- '2008-08-08 12:30:00'
select from_unixtime(1218169800, '%Y %D %M %h:%i:%s %x'); -- '2008 8th August 12:30:00 2008'
3. MySQL 时间戳(timestamp)转换、增、减函数:
timestamp(date) -- date to timestamp
timestamp(dt,time) -- dt + time
timestampadd(unit,interval,datetime_expr) --
timestampdiff(unit,datetime_expr1,datetime_expr2) --
请看示例部分:
select timestamp('2008-08-08'); -- 2008-08-08 00:00:00
select timestamp('2008-08-08 08:00:00', '01:01:01'); -- 2008-08-08 09:01:01
select timestamp('2008-08-08 08:00:00', '10 01:01:01'); -- 2008-08-18 09:01:01
select timestampadd(day, 1, '2008-08-08 08:00:00'); -- 2008-08-09 08:00:00
select date_add('2008-08-08 08:00:00', interval 1 day); -- 2008-08-09 08:00:00
MySQL timestampadd() 函数类似于 date_add()。
select timestampdiff(year,'2002-05-01','2001-01-01'); -- -1
select timestampdiff(day ,'2002-05-01','2001-01-01'); -- -485
select timestampdiff(hour,'2008-08-08 12:00:00','2008-08-08 00:00:00'); -- -12
select datediff('2008-08-08 12:00:00', '2008-08-01 00:00:00'); -- 7
MySQL timestampdiff() 函数就比 datediff() 功能强多了,datediff() 只能计算两个日期(date)之间相差的天数。
六、MySQL 时区(timezone)转换函数
convert_tz(dt,from_tz,to_tz)
select convert_tz('2008-08-08 12:00:00', '+08:00', '+00:00'); -- 2008-08-08 04:00:00
时区转换也可以通过 date_add, date_sub, timestampadd 来实现。
select date_add('2008-08-08 12:00:00', interval -8 hour); -- 2008-08-08 04:00:00
select date_sub('2008-08-08 12:00:00', interval 8 hour); -- 2008-08-08 04:00:00
select timestampadd(hour, -8, '2008-08-08 12:00:00'); -- 2008-08-08 04:00:00