MYSQL的创建和删除数据库
mysql -uroot -proot
mysql> show databases; --展示所有的数据库
-----------------------------------------
Databases
-----------------------------------------
information_schema
mysql
performance_schema
sys
test
----------------------------------------
use information_schema;
show tables;
结果可以看到有很多与列相关的表以及和存储引擎有关的表以及表有关的表。
MYSQL安装好后,自带的数据库:
1.information_schema
information_schema提供了访问数据库元数据的方式。(元数据时关于数据的数据,如数据库名和表名,列的数据类型,或者访问权限等。有时用于表述该信息的其他术语包括“数据字典”和“系统目录”)
换句话说,information_schema是一个信息数据库,他保存着关于mysql服务器所维护的所有其他数据库的信息(如数据库名,数据库的表,表列的数据类型与访问权限等),在information_schema中,有几张只读表,他们实际上是视图,而不是基本表。
2.mysql
mysql的核心数据库,类似于sql server中的master表,主要负责存储数据库的用户,权限设置,关键字等mysql自己需要使用的控制和管理信息。(常用的,在mysql.user表中修改root用户的密码)。
3.performance_schema
主要用于收集数据库服务器性能参数,并且库里表的存储引擎均为performance_schema,而用户是不能创建存储引擎为performance_schema的表,mysql 5.7默认是开启的。
4.sys
sys库所有的数据源来自:performance_schem。目标是把performance_schema的复杂度降低,让DBA能更好的阅读这个库里的内容,让DBA更快的了解DB的运行情况。
数据库建库语句:
create database my1;
--如果创建一个同名测数据库会报错:
create database my1;
报错信息:
ERROR :1007(HY000):Can't create database 'my1';database exists
解决方法:
create database if not exists my1;
--查看mysql字符集
show character set;
--列出字符集的字符序规则
show collation;
--创建数据库包括字符集和字符序规则:
create database if not exists test character set 'utf8mb4' collate 'utf8mb4_general_ci';
--删除数据库
drop database my1;
--mysql数据库改名:
rename database old_db_name to new_db_name;
2.测试数据加载
要规范:关键字用大写,自己添加的用小写。
create database hr;
show databases;
use hr;
select database(); --查看当前表使用的数据库
CREATE TABLE departments
( department_id INT(4),
department_name VARCHAR(30),
manager_id INT(6),
location_id INT(4),
PRIMARY KEY (department_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
同理创建employees表
都添加数据
3.SQL_MODE
在实际工作中,在Mysql中写sql语句,首先应该设置系统变量@@sql_mode。
如果不设置,一些操作会导致非法数据进入到表中,表现出和ORACLE等其他数据库完全不同的行为。
为和ORACLE保持一致,可以在数据库的配置文件my.cnf中添加配置(10项):
sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,
ONLY_FULL_GROUP_BY,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,
NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,
PIPES_AS_CONCAT,ANSI_QUOTES
各项含义如下:
STRICT_TRANS_TABLES:
在该模式下,如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做限制。必须设置,以后各项可能依赖于该项的设置。
NO_ENGINE_SUBSTITUTION:
如果需要的存储引擎被禁用或者未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常。
ONLY_FULL_GROUP_BY:
对于GROUP BY操作,如果在SELECT中出现单独的列,没有在GROUP BY 子句中出现,那么这个sql时不合法的。
NO_AUTO_VALUE_ON_ZERO:
该值影响自增长列的插入。默认设置下,插入0或者NULL代表生成下一个自增长值。如果用户希望插入的值为0,而该列又是自增长的,那么这个选项就有用了。
NO_ZERO_IN_DATE:
在严格模式下,不允许日期和月份为零。
NO_ZERO_DATE:
设置该值,mysql数据库不允许插入零日期,插入零日期会抛出错误而不是警告
ERROR_FOR_DIVISION_BY_ZERO:
在INSERT或UPDATE过程中,如果数据被零除,则产生错误而非警告。如果未给出该模式,那么数据被零除时MYSQL会返回NULL
NO_AUTO_CREATE_USER:(在MYSQL 8.0已经废除):
禁止GRANT语句创建密码为空的用户。
PIPES_AS_CONCAT:
将“||”视为字符串的连接操作符而非或运算符,这和Oracle数据库时一样的,也和字符串的拼接函数concat相类似。
ANSI_QUOTES:
启用ANSI_QUOTES后,不能用双引号来引用字符串,因为它被解释为识别符
也可以在命令行查看和设置sql_mode变量
查看全局的以及当前会话的sql_mode设置
SELECT @@global.sql_mode,@@session.sql_mode;
设置全局的以及当前会话的sql_mode设置:
SET
@@global.sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,
ONLY_FULL_GROUP_BY,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,
NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,
PIPES_AS_CONCAT';
SET
@@session.sql_mode='TRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,
ONLY_FULL_GROUP_BY,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,
NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,
PIPES_AS_CONCAT';
全局设置影响从那时起新连接的所有客户端,设置SESSION 变量只影响当前的客户端
SELECT查询语句操作
SELECT * | {[DISTINCT] column [alias],…}
FROM table;
SELECT 标识要显示的列。
FROM标识包含这些列的表
术语
语句:一条语句由多个子句构成。
子句:子句是一条语句的组成部分。
SQL语句的语法表示规则:
大写字母表示关键字(保留字)
{ }大括号表示里面的内容必须写一个
[ ] 中括号表示里面的内容是可选的
|表示二选一
, …表示前面的内容可重复若干个
小写字母表示此处应该使用实际的名称。
编写SQL语句注意事项
SQL 语句不区分大小写,关键字和列名不区分 ,但是表名区分大小写的。
可以在一行或者多行上输入SQL语句。
关键字不能缩写或者跨行分隔。
子句通常放在单独的行上。
缩进用于增强可读性。
每条语句以分号结束。
列标题默认值
SELECT 语句返回的结果叫结果集(RESULTSET)。他是一个表格。
结果集的列标题由SELEC子句中的列名或表达式决定,大小写和列名的大小写保持一致。列标题是左对齐的。
DESC 表名 --查看表的数据结构
DESC值KEY栏的值代表的意思
1.使用mysql数据库desc 表名时,我们看到key那一栏,可能会有4种值,即 ‘’,‘PRI’,‘UNI’,'MUL。如果key是空的,那么该列值可以重复,表示该列没有索引,或者是一个非唯一的复合索引的非前导列。
2.如果key是PRI,那么该列是主键的组成部分。
3.如果key是UNI,那么该列是一个唯一值索引的第一列(前导列),并不能含有空值(NULL)。
4.如果key是MUL,那么该列的值可以重复,该列是一个非唯一缩阴的前导列(第一列)或者是一个唯一性索引的组成部分,但是可以含有空值NULL。
字面量
字面量:就是一个不变的,固定的值。字面量总是有一个数据类型。
整型字面量:不带小数点的整数。如 12 -50 +80
小数字面量:带或者不带小数点的数值。如:49 18.47 +5.38 -0.47
浮点字面量:就是小数字面量后面跟着一个指数。如 -34e2 0.16e4 4e-3
字符串字面量:使用双引号或者单引号括起来的字母或数字的组合。引号定义了字符串的开头和结尾,他们本身不是字面量的一部分。字符串字面量中也可以包含引号。为了在字面量中表示一个单引号,需要使用双引号。“don’t”或者’don"t’
日期字面量:由年月日3个部分组成。mysql允许该字面量写作一个字符串字面量或者整形字面量。
字符串写法例如:‘1991@6@19’ ,‘1980-12-08’,‘1991-6-19’
整数写法:19801208 19910619 991111
强烈建议使用日期字面量时,采用字符串写法,并且年份写4位数字。
设置@@sql_mode中包含“ansi_quotes”,使得日期字面量和时间字面量只能使用但引号括起来。
日期字面量的取值范围为1000年1月1日到9999年12月31日,其中‘0000-00-00’是允许的,叫做零日期,它可以用来表示某个还不知道的日期,日期有一个合法的年份但是月或者日部分为0的日期也是允许的,也叫做零日期,如 ‘2006-00-00’
mysql 5.7对time,datetime,timestamp值提供了存储小数秒的支持,要想列可以存储小数秒,定义列时必须指定小数秒的精度。其中,TIME,DATETIME,或者TIMESTAMP,精度是0-6,如果省略精度,默认是0.
当插入一个带有小数秒的TIME,DATE,TIMESTAMP值时,如果小数秒的部分超过了列的小数秒的精度,那么会自动四舍五入。
日期时间字面量和时间戳字面量的区别:
年部分的取值范围:前者年的部分时1000-9999,后者年的部分时1970-2037
时间戳字面量在存取时会自动根据时区进行转换:在保存到表中时,自动按UTC(0时区)做转换;当从表中查询时,自动按客户端会话时区做转换。
--查看当前客户端的时区设置
SELECT @@time_zone;
--将客户端的时区修改为东时区
SET time_zone='+10:00';
SELECT @@time_zone;
可以用下面的方法查询当前的服务器和每个客户端连接的时区:
SELECT @@global.time_zone,@@session.time.zone;
timeZone值为字符串,表示相对UTC的偏移量,例如‘+10:00’或‘-6.00’。如果已经创建并装入mysql数据库中的时区相关表,你还可以使用命名的时区,例如:‘US/Eastern’。
布尔字面量:它有两个值:true(1)和false(0)
limit,WHERE ,ORDER BY
字符串和日期值用单引号引起来。
字符值区分大小写,日期值区分格式。
比较操作:
=(等于),>(大于),>=(大于等于),<(小于),<=(小于等于),<>(不等于),!=(不等于),BETWEEN AND (在…和…之间),IN(在…范围之内),LIKE(像…),IS NULL(空)
使用like运算符对有效的字符串值执行通配符搜索。
%表示0个或者多个字符。
_表示一个字符。
SELECT * FROM employee;
--输出查询的前面10行内容
SELECT * FROM employee LIMIT 10;
--找到工资最高的10个人
SELECT * FROM employee ORDER BY salary DESC LIMIT 10;
--找到 收入排在第3到第5位的人(收入最高排序)
SELECT * FROM employee ORDER BY salary DESC LIMIT 2,3;
SELECT * FROM employee WHERE depart_id=90;
SELECT * FROM employee WHERE last_name='King';
SELECT * FROM employee WHERE hire_date='1987-06-17';
SELECT * FROM employee WHERE salary BETWEEN 2500 AND 3500;---(在2500和3500之间,包括2500和3500)
和
SELECT * FROM employee WHERE salary >= 2500 AND salary <= 3500;相同
--得到名字以Sa开头的人
SELECT * FROM employee WHERE last_name REGEXP '^Sa';
--得到名字包含字母a,b或c的人
SELECT * FROM employee WHERE last_name REGEXP '[abc]';
--得到名字包含字母n的,并且连续出现2次的人
SELECT * FROM employee WHERE last_name REGEXP '[n][n]';
ORDER BY子句
使用ORDER BY 子句对检索到的行进行排序:
ASC:升序排序,默认
DESC:降序排序
SELECT last_name,job_id,department_id,hire_date FROM employee
ORDER BY department_id;
SELECT employee_id,last_name,salary*12 annsal FROM employee
ORDER BY annsal;
SELECT last_name,job_id,department_id,hire_date FROM employee
ORDER BY 3;–代表按照department_id排序
用户变量
定义语法:
1)SET @变量名{=|:=}value [,@变量名{=|:=} value,…]
SET @PI=3.1415926;
SELECT @PI;
SET @ABC=5,@DEF='ing',@GHI=date('2004-01-01');
SET @a=1;
SET @a=5;@b=@a;
SELECT @b
这里注意,变量b的值时1(a的老值),而不是5(a的新值)。因为mysql首先确定等号右边所有表达式的值(此时@a=1),然后再把值赋给变量(即5给@a,1给@b)
2)使用SELECT语句定义变量
这种语法:1)会返回1行 2)只能使用:=,不能使用=。=这里被看作比较操作符。
SELECT @EMPNO := 7 ;
SELECT @name:='tom',@town :='Spring';
--查询King的姓名,员工编号和部门,并保存到3个变量中
SELECT @name := last_name,@empno :=employee_id,@deptno := department_id FROM emplyees WHERE empployee_id=100;
注意:如果SELECT查询返回多行,就把最后一行的值赋给变量,
而不会抛出异常
SELECT @empno :=105 FROM employees WHERE employee_id < @empno;
注意:这条语句不会反悔编号小于105的人,因为where子句再select 语句之前执行。
set @sal=(SELECT salary from hr.employees where employee_id=100);
select @sal;
用户变量的生命周期
只要会话没有结束,用户变量就一直使用。如果想在一个用户会话中保存变量的值,以便在另一个用户会话中使用,那么就必须把这些变量值保存到一个表中。
CREATE TABLE VARIABLES(
varname char(30) NOT NULL PRIMARY KEY,
varvalue char(30) NOT NULL
);
SET @var1==100,@var2='john';
INSERT INTO VARIABLES('var1',@var1);
INSERT INTO VARIABLES('var2',@var2);
单行函数
单行函数对查询反悔的每一行执行一次,并返回一个结果。
函数可以有0个或者多个参数。
单行函数可以嵌套
字符串函数
--1.LOWER 将字符串参数值转换为全小写字母后返回
SELECT LOWER('SQL,COURSE');
--2.UPPER 将字符串转换为全大写字母后返回
SELECT UPPER('sql course');
---3.CONCAT(str1,str2,...) 将多个字符串参数首尾相连后返回
SELECT CONCAT('MY','S','QL')
注意:如果有任何参数为null,则函数返回 null,如果参数时数字,则自动转化为字符串。
--4.CONCAT_WS(separator,str1,str2...) 将多个字符串以给定的分隔符(第一个引号的内容)separator首尾相连后返回,
SELECT CONCAT_WS(',','First_name','Second_name','Last_name');
结果:First_name,Second_name,Last_name
注意:如果有任何参数为null,则函数不返回null,而是直接忽略它
SELECT CONCAT_WS(',','First_name',null,'Last_name');
结果:First_name,Last_name
--5.SUBSTR(str,pos[,len]) 从源字符串str中的指定位置pos开始取一个字符串并返回。len自定字符串的长度,如果省略则一直取道字符串的末尾。该函数时SUBSTRING()的同义词,len为负值表示从源字符串的尾部开始取起。
SELECT SUBSTR('hello world',5);
结果:o world
SELECT SUBSTR('hello world',5,3);
结果:o w
SELECT SUBSTR('hello world',-5);
结果:world
--6.LENGTH(str) 返回字符串的存储长度
SELECT LENGTH('text'),LENGTH('你好');
结果:4 6
--7.CHAR_LENGTH 返回字符串中的字符个数
SELECT CHAR_LENGTH('text');
--8.INSTR(str,substr) 从源字符串str中返回子串substr第一次出现的位置
SELECT INSTR('fooaprapr','apr');
结果:4
--9.LPAD(str,len,padstr) 在源字符串的左边填充给定的字符padstr到指定的长度len,返回填充后的字符串
SELECT LPAD('hi',4,'?');
结果:??hi
SELECT LPAD(emplyee_id,6,0) FROM employees ;
结果:000100
--10.RPAD(str,len,padstr)在源字符串的右边填充给定的字符padstr到指定的长度len,返回填充后的字符串
SELECT RPAD('hi',4,'?');
结果:hi??
--11.TRIM() 从源字符串str中去掉两端,前缀或者后缀字符并返回。如果不指定remstr,则去掉str两端的空格,不指定both,leading,trailing,则默认为both
SELECT TRIM(' apr '); --去掉两端空格
结果:apr
SELECT TRIM(LEADING 'x' FROM 'xxxaprxxx'); --去掉前面字符串
结果:aprxxx
SELECT TRIM(BOTH 'x' FROM 'xxxaprxxx');--去掉前面和后面
结果:apr
SELECT TRIM(TRAILING 'x' FROM 'xxxaprxxx'); --去掉后面
结果:xxxapr
--12.REPLACE(str,from_str,to_str) 在原字符串str中查找子串from_str(大小写敏感),找到后使用替代字符串to_str替换它。返回替换后的字符串。
SELECT REPLACE('www.mysql.comw','w','p');
结果:ppp.mysql.comp
--13.LTRIM(str),RTRIM(str) 去掉字符串的左边或者右边的空格
SELECT LTRIM(' APRAPR ') rs1,RTRIM(' aprapr ') rs2;
结果:APRAPR , aprapr
14.REPEAT(str,count) 将字符串str重复count次后返回
SELECT REPEAT('MySql',3);
结果:MySqlMySqlMySql
15.REVERSE(str) 将字符串str反转后返回
SELECT REVERSE('abc');
结果:cba
16.SPACE(N) 返回由N个空格构成的字符串
SELECT SPACE(6);
结果:6个空格
SELECT CONCAT('1',SPACE(10),'2')
结果 1 2
17.LEFT(str,len)返回最左边的len长度的子串
SELECT LEFT('fooaprapr',5);
结果:fooap
18.RIGHT(str,len) 返回最右边的len长度的子串
SELECT RIGHT('fooaprapr',4);
结果:rapr
19.STRCMP(expr1,expr2) 如果两个字符串时一样的则返回0,如果第一个小于第二个则返回-1,否则返回1
SELECT STRCOMP('text','text2'),STRCOMP('text2','text'),STRCOMP('text','text');
结果:-1 ,1,0
数字函数
1.ROUND(X[,D]) 四舍五入
将数字x四舍五入到指定的小数位数d,如果不指定d,则默认为0,如果d时负数,则表示从小数的左边进行四舍五入
SELECT ROUND(1.58),ROUND(1.298,1);
结果:2 ,1.3
SELECT ROUND(1.298,0),ROUND(23.298,-1);
结果:1, 20
2.TRUNCATE(X,D) 将数字X截断到指定的小数位数D(不四舍五入),D为0表示不要小数,如果d是负数,表示从小数点的左边进行截断
SELECT TRUNCATE(1.999,1),TRUNCATE(1.999,0);
结果:1.9,1
SELECT TRUNCATE(-1.999,1),TRUNCATE(122,-2);
结果:-1.9,100
3.MOD(N,M),N%M,N MOD M
返回数字N除以m后的余数,注意:余数可以有小数,除数为0不抛出异常。
SELECT MOD(10,3),10 % 3,10 MOD 3;
结果:1,1,1
4.CEIL(X) ,CEILING(X) 返回不小于x的最小整数
SELECT CEILING(1.23),CEIL(-1.23);
结果;2,-1
5.FLOOR(x)返回不大于x的最大整数
SELECT FLOOR(1.23),FLOOR(-1.23);
结果:1,-2
6.RAND(),RAND(N)
返回一个随机的浮点数v,0<=v<=1.0,如果指定整数N,则用作种子值,它产生一个可重复的数字序列。
SELECT i,rand() from t;
和 SELECT i,rand() from t;每次产生的随机数是不相同的。
SELECT i,rand(3) from t;
和 SELECT i,rand(3) from t;每次产生的随机数是相同的。
当在where子句中使用rand()时,每次当where执行时都要重新计算rand();
不能在 order by子句中使用带有随机值的列,但是可以以随机的顺序从表中检索。
SELECT * FROM emplyees ORDER BY RAND();
ORDER BY RAND() 常和LIMIT子句一起使用。
SELECT * FROM table1,table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000;
日期时间函数
**NOW(fsp),SYSDATE(fsp)**返回服务器的当前日期和时间。格式有‘YYYY-MM-DD HH:MM:SS’或者‘YYYYMMMDDHHMMSS’.具体那种格式以来语用在字符串还是数字上下文。fsp指定小数秒的精度,取值0-6
SYSDATE()返回的是函数执行时的时间,now()返回的事语句执行时的时间。一般用now()而不用sysdate()。
SELECT NOW();
结果:2021-05-30 23:24:43
SELECT NOW()+0;
结果:20210530232459
CURDATE() 返回服务器的当前日期。格式有‘YYYY-MM-DD’ 或者YYYYMMDD。具体哪中格式以来于用在字符串还是数字上下文中;
SELECT CURDATE(),CURDATE()+0;
结果:2021-05-30 ,20210530
CURTIME() 返回服务器的当前时间。格式‘HH:MM:SS’或者HHMMSS。同义词有CURRENT_TIME,CURRENT_TIME().
SELECT CURTIME(),CURTIME+0;
结果:23:30:20,233020
DATE_ADD(date,INTERVAL expr unit),
DATE_SUB(date,INTERVAL expr unit)
分别为给定的日期date加上或者减去一个时间间隔值expr。unit是时间间隔的单位(20个)
SELECT NOW(),DATE_ADD(NOW(),INTERVAL 1 DAY);--加一天
SELECT NOW(),DATE_ADD(NOW(),INTERVAL 1 HOUR);--加一小时
SELECT NOW(),DATE_ADD(NOW(),INTERVAL 1 MINUTE);--加一分钟
SELECT NOW(),DATE_ADD(NOW(),INTERVAL 1 SECOND);--加一秒
SELECT NOW(),DATE_ADD(NOW(),INTERVAL 1 MICROSECOND);--加一毫秒
SELECT NOW(),DATE_ADD(NOW(),INTERVAL 1 WEEK);--加一星期
SELECT NOW(),DATE_ADD(NOW(),INTERVAL 1 MONTH);--加一月
SELECT NOW(),DATE_ADD(NOW(),INTERVAL 1 QUARTER);--加一季度
SELECT NOW(),DATE_ADD(NOW(),INTERVAL 1 YEAR);--加一年
SELECT DATE_ADD('2100-12-31 23:59:59',INTERVAL '1:1' MINUTE_SECOND)--加1分1秒
SELECT DATE_SUB('2005-01-01 00:00:00',INTERVAL '1 1:1:1' DAY_SECOND)--加1天1小时1分钟1秒
不使用函数也可以进行表达式加减:
SELECT '2008-12-31 23:59:59' +INTERVAL 1 SECOND;
结果:2009-01-01 00:00:00
SELECT '2005-01-01' -INTERVAL 1 SECOND;
DATEDIFF(expr1,expr2)
返回两个日期相减相差的天数。只有日期部分参与计算。
SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');
结果:1
SELECT DATEDIFF('2010-11-30 23:59:59','2010-12-31');
TIMEDIFF(expr1,expr2)返回两个日期相减相差的时间数,两个参数类型必须相同。
SELECT TIMEDIFF('2000:01:01 00:00:00','2000:01:01 00:00:01');
SELECT TIMEDIFF('2008-12-31 23:59:59.000001','22008-12-31 23:59:59.000002');
选取日期时间的各个部分:日期,时间,年,季度,月,日,小时,分钟,秒,微秒
SELECT NOW(),DATE(NOW()); --日期
SELECT NOW(),TIME(NOW());--时间
SELECT NOW(),YEAR(NOW());--年
SELECT NOW(),QUARTER(NOW());--季度
SELECT NOW(),MONTH(NOW());--月
SELECT NOW(),WEEK(NOW());--周
SELECT NOW(),DAY(NOW());--日
SELECT NOW(),HOUR(NOW());--小时
SELECT NOW(),MINUTE(NOW());--分钟
SELECT NOW(),SECOND(NOW());--秒
SELECT NOW(),MICROSECOND(NOW());--微秒
dayofweek(date),dayofmonth(date),dayofyear(date)分别返回日期在一周,一月,一年中是第几天
SELECT now(),dayodweek(now());
结果:2021-05-30 23:37:34 ,1
select now(),dayofmonth(now());
结果:2021-05-30 23:37:34 ,30
select now(),dayofyear(now());
dayname(),monthname()返回星期和月份的名称。名称是中文还是英文由系统变量 lc_time_names控制,默认是英文。
show VARIABLES LIKE 'lc_time_names';
结果:en_US
select dayname(now()),monthname(now());
结果:Sunday,May
set lc_time_names='zh_CN';
select dayname(now()),monthname();
结果:星期天,五月
转换函数
数据类型转换:隐式数据类型转换和显示数据类型转换
在表达式中,mysql可以自动转换一下内容:
两个值进行运算或者比较,首先要求数据类型必须一致。如果发现类型不一致的情况,mysql就尝试做隐式类型转换,
SELECT 1+'1'; --字符转换成数字
结果:2
SELECT CONCAT(1,'text');
结果:1 text
显示数据类型转换:
CAST(expr AS type)
将任意类型的表达式expr转换成指定类型的type的值。type可以是以下任意类型之一:
BINARY([N]):二进制字符串,转换后长度小于N个字节(不足长度N则尾部不上0x00)
CHAR[(N)]:字符串,转化后长度小于N个字符
DATE:日期
DECIMAL[(M[,N])]:浮点数,m为数字有效位(包括整数部分和小数部分)n为小数点后的位数
SIGNED[INTEGER]:有符号整数
TIME:时间
UNSIGNED:无符号整数
字符串转成数字:
转成decimal时,从头扫描字符串直到第一个部位数字的字符为至,对截断的那一位进行四舍五入
SELECT CAST('36.42a' AS decimal);
结果:36
SELECT CAST('36.72a' AS decimal);
结果:37
SELECT CAST('36.42a' AS decimal(4));
结果:36
SELECT CAST('36.52a' AS decimal(4));
结果:37
SELECT CAST('36.42a' AS decimal(1));
结果:9
###########
如果m的长度小于实际的数字位数时,会转换成设个位数的最大值。
如果m,n都限定,必须满足小数点后的n位小数。
#############
SELECT CAST('36.42a' as decimal(2,1));
结果:9.9
SELECT CAST('36.42a' as decimal(4,1));
结果:36.4
SELECT CAST('36.42a' as decimal(4,2));
结果:36.42
select cast('2021-06-01' as datetime);
结果:2021-06-01 00:00:00
select cast('2021-06-01' as date);
结果:2021-06-01
select cast('08:08:08' as time);
结果:08:08:08
数字到字符串
select cast(123 as char);
结果:123
select cast(123 as binary);
在5.7下可以转化成123,但是在8.0下只能转化为16进制的存储数字。
CONVERT函数
convert函数的作用和cast函数几乎相同,但是它可以把字符串从一种字符集转换成另一种字符集。
select convert('abc' using utf8);
日期字符串转化成函数
DATE_FORMAT(date,fromat)将日期date按照给定的模式format转化成字符串。
TIME_FORMAT(date,format) format种只能使用时,分,秒和微秒模式元素。
select date_format('2009-10-04 22:23:00','%W %M %Y');
结果:Sunday October 2009
select date_format('2007-10-04 22:23:00','%H:%i:%s');
结果:22:23:00
select time_format(now(),'%H:%i:%s');
结果:22:23:01
STR_TO_DATE(str,format)将字符串str以指定的模式format转换成日期。format种可以包含模式元素和字面量,字面量必须匹配str种的字面量。
select str_to_date('01,5,2023','%d,%m,%Y');
结果:2023-05-01
select str_to_date('May 1,2023','%M %d,%Y');
结果:2023-05-01
IFNULL(expr1,expr2)||NULLIF(expr1,expr2)
如果第一个expr1不为null则直接返回它,否则返回第二个参数expr2.返回值时数字或者字符串。它相当于oracle种的nvl函数。
select ifnull(1,0);
结果:1
select ifnull(null,10);
结果:10
IF(expr1,expr2,expr3)如果第一个参数expr1为true(expr1<>0 and expr1 <> null),则返回第二个参数expr2,否则返回第三个参数expr3,返回值时数字或者字符串。
select if(1>2,2,3),if(1<2,'yes','no');
结果:3,yes
CASE
WHEN 条件1 THEN use_expression1
WHEN 条件2 THEN use_expression1
WHEN 条件3 THEN use_expression1
ELSE
END
SELECT last_name,job_id,salary,
(CASE job_id
WHEN 'IT_PROG' THEN 1.10*salary
WHEN 'ST_CLERK' THEN 1.15*salary
WHEN 'SA_REP' THEN 1.20*salary
ELSE salsry
END )
'REVISED_SALARY'
聚合函数
where子句中不能使用聚合函数。
select avg(salary), #平均值
max(salary),#最大值
min(salary),#最小值
sum(salary) #工资的总和
from employees;
select min(hire_date),
max(hire_date)
from employees;
select department_id,job_id,count(last_name)
from employees
group by department_id;
--这个sql时错误的,因为job_id没有分组。不用写在group by后的,必须用count(),avg()等聚合函数。
select department_id,avg(salary)
from employees
group by depart_ment_id
having avg(salary) > 8000;