mysql常用sql语句的练习笔记,方便不记得时,翻出来看看
+ grant all privileges on . to '用户名'@'主机' identified by '密码';创建用户 + show databases; + 如果数据库太多可以过滤, show databases like "%abd%"; + use dbname; + show tables; + 如果表太多可以过滤, show tables like "%abd%"; + drop database dbanme; + drop table tbname; + drop view view_name; 删除视图 + desc tablename; 查看表的结构 + show create table/view 表名/视图名 + show full tables; 会返回 表名和table_type + show full tables where table_type = 'view';显示所有的视图 + show full tables where table_type = 'base table';显示所有的视图 + show status; 服务器状态 + select version(); mysql的版本 + select database(); 当前数据库名 + select user(); 当前用户 + show variables; 显示服务器变量 + delete/drop/truncate + delete是DML语句,不会自动提交。drop/truncate都是DDL语句,执行后会自动提交 + 效率方面:drop > truncate > delete + 当你不再需要该表时, 用 drop;当你仍要保留该表,但要删除所有记录时, 用 truncate;当你要删除部分记录时(always with a WHERE clause), 用 delete. + 参考连接 + MySQL在控制台上以竖行显示表格数据 最后+'\G' + 例如, select * from user limit 10 \G;
+ CREATE DATABASE new_db_name; + RENAME TABLE db_name.table1 TO new_db_name.table1, + db_name.table2 TO new_db_name.table2; + DROP DATABASE db_name;
+ ALTER DATABASE study CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
+ create database per_test default charset utf8 collate utf8_general_ci; + create database per_test character set utf8 collate utf8_general_ci; + 创建数据库是无法指定数据库的引擎,只能修改mysql的配置文件设置默认引擎,或者在创建表时指定数据引擎
create table test1(
id int(3) unsigned not null primary key auto_increment,
name varchar(20) not null,
last_update timestamp default current_timestamp on update current_timestamp
) engine=Innodb auto_increment=1001 default charset=utf8;找到 auto_increment_increment 变量设置的地方;VI里面可以用 "/auto_increment_increment" 找到。 找到后设置 auto_increment_increment=1; auto_increment_offset=1001;
SET @@auto_increment_increment=10; //设置步长
其他全局变量也可在此配置文件里面永久设置好。 配置文件修改好后,要重启mysql服务才会生效。
create table student( -> id int(8) primary key auto_increment, -> name varchar(20) not null, -> grade int(1), -> gender char(10) -> ); create table stu_farmily( id int(3) primary key auto_increment, child_name varchar(20) not null, father_name varchar(20) not null, mather_name varchar(20) not null, phone varchar(20), address varchar(100));
create table teacher(
id int(3) unsigned primary key auto_increment,
name varchar(100) not null,
age int(1) not null default 0,
worktime varchar(50),
create_time timestamp not null default current_timestamp,
last_update timestamp not null default current_timestamp on update current_timestamp
)engine=Innodb default charset=utf8;insert into student (name, grade,gender) values('jack',40,'M'), ('tom',100, 'M'),('lily',90,'F'), ('qinming', 90, 'M'), ('husanniang', 88, 'F'), ('sunerniang', 66, 'F'), ('wusong', 86, 'M'), ('linchong', 92, 'M'), ('yanqing', 90, NULL), ('test3m',70,'F'),('test_jim',30,'M'), ('jim',30,'M');
insert into student(name) values('test2),('test3'),('test4'); insert into student(name, gender) values('test5','M'),('test6','F'),('test7','M'); insert into stu_farmily(child_name,father_name,mather_name,phone,address) values ('lucy','lucy_f','lucy_m','13811112200',null), ('lily','lily_f','jlily_m','13811112222','street 1 building 115'), ('tom','tom_f','tom_m','13811112233','street 2 building 111'), ('jim','jim_f','jim_m','13811112244','street 2 building 113'), ('test3m','test_f','test_m',null,null);
('jack','jack_f','jack_m','13811112211','street 1 building 109'),
在 MySQL 中可以使用 ALTER TABLE 语句来改变原有表的结构,例如增加或删减列、创建或取消索引、更改原有列类型、重新命名列或表等。 基本语法 修改表指的是修改数据库中已经存在的数据表的结构。MySQL 使用 ALTER TABLE 语句修改表。常用的修改表的操作有修改表名、修改字段数据类型或字段名、增加和删除字段、修改字段的排列位置、更改表的存储引擎、删除表的外键约束等。
常用的语法格式如下: ALTER TABLE <表名> [修改选项] 修改选项的语法格式如下: { ADD COLUMN <列名> <类型> [约束条件] [FIRST|AFTER 已存在的字段名] default <值> | CHANGE COLUMN <旧列名> <新列名> <新列类型> | ALTER COLUMN <列名> SET DEFAULT <默认值>/DROP DEFAULT | MODIFY COLUMN <列名> <类型> | DROP COLUMN <列名> | RENAME TO <新表名> } 例如 + alter table stu_farmily rename to family; 更改表名 + alter table student add column test_id int(3) default 0 after name; 在name后面新增列 + alter table student change column test_id test int(1); 修改列名和类型 + alter table student alter column test set default 5; 设置默认值 + alter table student modify test varchar(10); 修改字段类型 + alter table student drop test; 删除字段
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition] [ORDER BY ...] [LIMIT row_count]
例如: update family set father_name = 'test3m_f' where child_name = 'test3m' limit 1; LIMIT子句是一个与行匹配的限定。只要发现可以满足WHERE子句的row_count行,则该语句中止,不论这些行是否被改变。 如果一个UPDATE语句包括一个ORDER BY子句,则按照由子句指定的顺序更新行。
UPDATE [LOW_PRIORITY] [IGNORE] table_references SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition] UPDATE语法可以用新值更新原有表行中的各列。SET子句指示要修改哪些列和要给予哪些值。WHERE子句指定应更新哪些行。如果没有WHERE子句,则更新所有的行。如果指定了ORDER BY子句,则按照被指定的顺序对行进行更新。LIMIT子句用于给定一个限值,限制可以被更新的行的数目。 例如: update student set family_id =(select id from family where family.child_name = student.name); update student as s,family as f set s.family_id=f.id where s.name = f.child_name; 以上两个语句效果不一样,会导致没有查询结果的family_id 变为null, 在一个被更改的多表 UPDATE中,有些列被引用。您只需要这些列的MySQL UPDATE权限。有些列被读取了,但是没被修改。您只需要这些列的SELECT权限。 注释:您不能把ORDER BY或LIMIT与multiple-table UPDATE同时使用。
例如,update student set grade = grade +1 where grade is not null and grade < 100;
SELECT [DISTINCT] *|{字段名1, 字段名2, 字段名3,……} FROM 表名 [WHERE 条件表达式1] [GROUP BY 字段名 [HAVING 条件表达式2]] [ORDER BY 字段名 [ASC|DESC]] [LIMIT [OFFSET] 记录数]
带In关键字的语法为 select * | 字段名1, 字段名2,... from 表名 where 字段名 [NOT] IN (元素1, 元素2, 元素3, ...) Between AND关键字 带BETWEEN AND关键字的查询—判断某个字段的值是否在指定的范围之内 语法为: SELECT *|{字段名1,字段名2,……} FROM 表名 WHERE 字段名 [NOT] BETWEEN 值1 AND 值2
select name as 姓名, gender 性别, grade from student where grade not between 80 and 90 order by id limit 10 ;Distinct关键字的语句用于去除查询结果的重复记录。有时候,处于对数据的分析需求,需要过滤掉查询记录中重复的值。语法如下: SELECT DISTINCT 字段名,字段2 FROM 表名; select distinct gender from student;
判断某些列是否有空值。 在数据表中,某些列的值可能为空值NULL,空置不同于0,也不同于空字符串。
在MySQL中,使用IS NULL关键字来判断字段的值是否为空值,其语法格式为:
SELECT *|字段名1,字段名2,…… FROM 表名 WHERE 字段名IS [NOT] NULL select *from student where gender is null;
有时候需要对字符串进行模糊匹配,例如查询student表中name字段值’b’开头的记录, 为了完成类似功能,Mysql提供了Like关键字进行模糊查询。 LIKE关键字可以判断两个字符串是否相匹配。语法如下:
SELECT *|{字段名1,字段名2,……} FROM 表名 WHERE 字段名 [NOT] LIKE '匹配字符串'; 1.通配符% 匹配字符串指定用来匹配的字符串,其值可以是一个普通字符串,也可以是一个包含百分号%或者下划线_的通配字符串。 两个符号在匹配过程中有特殊含义。 select * from student where like 't%'; 匹配以t开头的信息 select * from student where name like '%i%'; 匹配包含i字母的name select * from student where name like '%i%g'; 这种情况是同时包含两种字符的name 2. 通配符_ 下划线_ 下划线通配符_仅仅匹配单个字符,如果要匹配多个字符,需要使用多个下划线通配符。 查询student表中name字段值以字符串‘test’开始,以字符串‘数字’结束 select * from student where name like 'test_'; 3.如要查询包含%和_的,需要在前面加转义字符\
注意:OR关键字和AND关键字可以一起使用,需要注意的是,AND优先级高于OR,因此当两者在一起使用时, 应该先运算AND量表的条件表达式,再运算OR两边的条件表达式。
COUNT函数用来统计记录的条数,语法格式如下: select COUNT(*) from 表名
sum是求和函数,用于求出表中某个字段所有值的总和,语法如下: select sum(字段名) from 表名 select sum(grade) as grade_sum from student;
AVG可以用于求出某个字段所有值得平均值,语法如下: select avg(字段名) from 表名 select avg(grade) as grade_sum from student;
max/min函数则是用于求最大值/最小值的函数,用于求出某个字段的最大值 语法如下: select max/min(字段名) from 表名 select max(grade) as grade_max from student;
从表中查询出来的数据可能是无序的,或者其排列顺序不是用户预期的。为了使查询结果满足用户的要求,可以使用ORDER BY对查询结果进行排序,语法格式如下:
SELECT 字段名1,字段名2,…… FROM 表名 ORDER BY 字段名1 [ASC | DESC],字段名2 [ASC | DESC]…… 默认是ASC,可以不写,是顺序; desc,是倒序。 select *from student where grade is not null and gender is not null order by grade desc, name; 先按第一个条件排序,如果第一条件的值相同,再按第二个条件排序
在对表中数据进行统计时,也可能需要按照一定的类别进行统计, 比如,分别统计student表中gender字段为“男” “女“, “NULL”的学生成绩之和。 在mysql中,可以使用group by按某个字段或者多个字段中的值进行分组,字段中值相同的为1组,其语法格式如下:
SELECT 字段名1,字段名2,…… FROM 表名 GROUP BY 字段名1,字段名2,……[HAVING 条件表达式];
HAVING关键字指定条件表达式对分组后的内容进行过滤。需要注意的是,Group BY一般和聚合函数一起使用,
select gender from student group by gender; 注意:select * from student group by gender; 会报错哦 group by 多个字段 select count(*)as num,gender,grade from student group by gender, grade; group by 但个字段,效果和select distinct 相近,只是distinct无法用聚合函数 select distinct gender from student; select gender from student group by gender; 如果查询的字段出现在Group By后,却没有包含在聚合函数中,该字段显示的是分组后第一条记录的值,这样可能会导致查询的结果与预期不符合。
select sum(grade) as gender_sum, avg(grade) as grade_avg, count(*) as gender_num,gender from student group by gender;
加上having的例子,性别不为空的 select sum(grade) as gender_sum, avg(grade) as grade_avg, count() as gender_num,gender from student group by gender having gender is not null; HAVING的条件一定是前面select后面的字段,如果要平均分大于70的 select sum(grade) as gender_sum, avg(grade) as grade_avg, count() as gender_num,gender from student group by gender having grade_avg>70 ;
Having关键字与where字句作用相同,都用于设置条件表达式对查询结果进行过滤,两者的区别在于,Having关键字后可以跟聚合函数,而where子句不可以。通常情况先Having关键字都和Group By一起使用,用于对分组后的结果进行过滤。 将student表中按照gender字段进行分组排序,查询出grade字段值之和小于300的分组 select sum(grade), gender from student group by gender having sum(grade)<300;
找出成绩最低的学生信息 select *from student where grade = (select min(grade) as grade_min from student);
SELECT expression1, expression2, ... expression_n FROM tables [WHERE conditions] UNION [ALL | DISTINCT] SELECT expression1, expression2, ... expression_n FROM tables [WHERE conditions];
找出不同表中,同一个字段,合并到一起 1. select distinct gender from student union select distinct gender from test1; 自动去重 2. select distinct gender from student union all select distinct gender from test1; 两个结果合并到一起,不去重
语法:select xxx from 表1 inner join 表2 on 条件 如:查询出所有学生 -> select a.*, b.father_name from student as a inner join family as b on a.name=b.child_name where a.grade is not null; 结果:返回都有值得数据,相当于视图
语法:select xxx from 表1 left join 表2 on 条件 如:查询出所有学生 -> select a.*, b.father_name from student as a left inner join family as b on a.name=b.child_name where a.grade is not null; 结果:以连接左边的表student为基础,补全所有father_name 信息,没有的会自动补 null
语法:select xxx from 表1 right join 表2 on 条件 如:查询出所有学生 -> select a., b.father_name from student as a right inner join family as b on a.name=b.child_name where a.grade is not null; 结果:以连接右边的表family为基础,补全所有student.的信息,没有的会自动补 null
对表访问方式,表示MySQL在表中找到所需行的方式,又称“访问类型”。 常用的类型有: ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)
1.mysql的时间类型 + date 3字节,1000-01-01/9999-12-31,YYYY-MM-DD,无法设置默认值 + time 3字节,'-838:59:59'/'838:59:59',HH:MM:SS,无法设置默认值 + year 1字节, 1901/2155, YYYY,无法设置默认值 + datetime 8字节,1000-01-01 00:00:00/9999-12-31 23:59:59,从5.6.5开始,,default now()或current_timestamp + timestamp 4字节,1970-01-01 00:00:00/2038-1-19 11:14:07(北京时间),default now()或current_timestamp + 它把客户端插入的时间从当前时区转化为UTC(世界标准时间)进行存储。查询时,将其又转化为客户端当前时区进行返回。 + 将时间转换为时间戳unix_timestamp, SELECT UNIX_TIMESTAMP('2019-02-22 13:25:07'); #1550813107 + 将时间戳转换为时间from_unixtime,SELECT FROM_UNIXTIME(1550813107); #2019-02-22 13:25:07 2. mysql的时间函数 + NOW() 获取当前日期和时间的函数。 + curdate() 获取当前的日期 + curtime() 获取当前时间 + date(date) 获取参数里面的,日期部分 + extract(unit FROM date), 获取返回日期/时间的单独部分,比如年、月、日、小时、分钟等等。 + unit 参数可以是下列的值:MICROSECOND、SECOND、MINUTE、HOUR、DAY、WEEK、MONTH、QUARTER、YEAR、SECOND_MICROSECOND、 MINUTE_MICROSECOND、MINUTE_SECOND、HOUR_MICROSECOND、HOUR_SECOND、HOUR_MINUTE、DAY_MICROSECOND、DAY_SECOND、 DAY_MINUTE、DAY_HOUR、YEAR_MONTH + select EXTRACT(YEAR_MONTH FROM now()) ; + date_add(date,interval expr type) 将日期添加指定的时间间隔。 + date 参数是合法的日期表达式。expr 参数是添加的时间间隔,+正数是未来,-负数是过去。 + type 参数可以是下列值:MICROSECOND、SECOND、MINUTE、HOUR、DAY、WEEK、MONTH、QUARTER、YEAR、SECOND_MICROSECOND、 MINUTE_MICROSECOND、MINUTE_SECOND、HOUR_MICROSECOND、HOUR_SECOND、HOUR_MINUTE、DAY_MICROSECOND、 DAY_SECOND、DAY_MINUTE、DAY_HOUR、YEAR_MONTH + 实例: select *from users where last_update > date_add(now(),interval -2 day); 查询2天内登陆过的用户信息 + date_sub(date,interval expr type) 将日期减去指定的时间间隔,相当于date_add用负数的效果 + datediff(date1,date2)获取两个日期之间的天数 + date1 和 date2 参数是合法的日期或日期/时间表达式。 + 实例:select id, username, datediff(now(),date(regist_time)) as reg_day from user; 查询用户注册时间 + dateformat(date,format) 格式化日期时间 + date 参数是合法的日期。format 规定日期/时间的输出格式。 + %a:缩写星期名, + %b:缩写月名, + %D:带有英文前缀的月中的天, + %M:月名, + %W:星期名, + %w:周的天 (0=星期日, 6=星期六) + %Y:年,4 位,%y:年,2 位,%c:月,数值,%m:月,数值(00-12),%d:月的天,数值(00-31),%e:月的天,数值(0-31), + %H:小时 (00-23),%h:小时 (01-12),%I:小时 (01-12),%i:分钟,数值(00-59),%S:秒(00-59),%s:秒(00-59),%f:微秒 + %r:时间,12-小时(hh:mm:ss AM 或 PM, + %p:AM 或 PM, + %k:小时 (0-23),%l:小时 (1-12) + %j:年的天 (001-366) + %T:时间, 24-小时 (hh:mm:ss) + %U:周 (00-53) 星期日是一周的第一天 + %u:周 (00-53) 星期一是一周的第一天 + %V:周 (01-53) 星期日是一周的第一天,与 %X 使用 + %v:周 (01-53) 星期一是一周的第一天,与 %x 使用 + %X:年,其中的星期日是周的第一天,4 位,与 %V 使用 + %x:年,其中的星期一是周的第一天,4 位,与 %v 使用 ``` #查询示例 #根据年月日查数据 select id,name, date_format(last_update,"%Y-%m-%d") as last_update from test1 where last_update="2020-06-12"; #根据年月查数据 SELECT *FROM tb_test WHERE DATE_FORMAT(update_time, '%Y-%m')='2021-01'; #根据年查数据 SELECT *FROM tb_test WHERE DATE_FORMAT(update_time, '%Y')='2022';
select * from 表名 where to_days(时间字段名) = to_days(now());
#近7天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(时间字段名)
#本月
SELECT * FROM 表名 WHERE DATE_FORMAT( 时间字段名, '%Y%m' ) = DATE_FORMAT( CURDATE( ) , '%Y%m' )
#询本季度数据
select * from ht_invoice_information where QUARTER(create_date)=QUARTER(now());
+ to_days() 从1970到现在的天数 3. 查询某一天数据的各种方法
SELECT * FROM test WHERE substring(Convert(char(10),update_time ,112),1,8)='20200601'
SELECT * FROM test WHERE update_time between '2020-06-01 00:00:00' and '2020-06-017 23:59:59'
SELECT * FROM test WHERE year(update_time ) = 2020 and month(update_time )= 06 and day(update_time ) = 01
SELECT * FROM test WHERE update_time > '2020-06-01' and update_time < '2020-06-02'
SELECT * FROM tests WHERE ( datediff ( update_time , '2020-06-01' ) = 0 )
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR (200),
body TEXT,
FULLTEXT (title, body) WITH PARSER ngram
) ENGINE = INNODB DEFAULT CHARSET=utf8mb4 COMMENT='文章表';
ALTER TABLE articles ADD FULLTEXT INDEX title_body_index (title,body) WITH PARSER ngram;
#自然语言模式
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('精神' IN NATURAL LANGUAGE MODE);
等于 SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('精神');
#BOOLEAN MODE
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+精神 -贯彻' IN BOOLEAN MODE);