mysql之DML和DQL

欢迎大家加入我的github项目,一起学习,一起发展
--->全栈工程师进阶学习站
--->我的前端学习笔记
--->行业内最新最群的报告,工作日每日更新

DML和DQL

1、存储引擎
插件式存储引擎是MySQL数据库最重要的特性之一,用户可以根据应用的需要选择如何存储和索引数据库,是否使用事务等。mySQL默认支持多种存储引擎,以适应不同领域的数据库应用需要。用户可以通过选择使用不同的存储引擎提高应用的效率,提供灵活的存储,用户设置可以按照自己的需要定制和使用自己的存储引擎,以实现最大程度的可定制性。

MySQL常用的存储引擎为MyISAM、InnoDB、MEMORY、MERGE,其中InnoDB提供事务安全表,其他存储引擎都是非事务安全表。

MyISAM是MySQL 5.0之前的的默认存储引擎。MyISAM不支持事务、也不支持外键,但其访问速度快,对事务完整性没有要求。

InnoDB事务型数据库的首选引擎,支持ACID事务,支持行级锁定, MySQL 5.5 起成为默认数据库引擎

InnoDB存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全。但是比起MyISAM存储引擎,InnoDB写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引。MySQL支持外键存储引擎只有InnoDB,在创建外键的时候,要求附表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引。

查看默认的存储引擎:
    SHOW VARIABLES LIKE '%storage_engine%'; 
指定表的存储引擎语法:
    CREATE TABLE 表名(
        #省略代码
    )ENGINE=存储引擎;
查看数据物理文件的存储地址:
    SHOW VARIABLES LIKE '%datadir%'; 

2、DML语句:数据库操纵语言 insert update delete
DDL语句:数据库定义语言 create alter drop truancate
DCL语句:数据库控制语言 grant commit rollback
DQL语句:数据库查询语言 select

3、insert语句
单条数据插入:
语法:INSERT INTO 表名 [(字段名列表)] VALUES (值列表);
注意:
字段名是可选的,如省略则依次插入所有字段(必须是所有字段,不能缺省)
多个列表和多个值之间使用逗号分隔
值列表和字段名列表一一对应
如插入的是表中部分数据,字段名列表必填
多条数据插入:
语法一:INSERT INTO 新表(字段名列表)VALUES(值列表1),(值列表2),……,(值列表n);
语法二:INSERT INTO 新表(字段名列表) select 字段1[字段2…] from 旧表
insert into stu2 select * from students;
注意:
为避免表结构发生变化引发的错误,建议插入数据时写明具体字段名!
查询结果在建表的同时插入数据
语法:
CREATE TABLE 新表(SELECT 字段1,字段2…… FROM 原表);
或者
CREATE TABLE 新表
AS
SELECT 字段1,字段2…… FROM 原表
示例:

        CREATE TABLE `phoneList`(
            SELECT `stu_name`,`mobile_no`
            FROM `students`);

        create table stu1 
        as 
        select stu_no,stu_name from students;

        create table stu2 
        as 
        select * from students where 1=2

4、update语句
语法:
UPDATE 表名 SET 字段1=值1,字段2=值2,…,字段n=值n
[WHERE 条件];
#省略where条件,全表更新

5、delete语句
语法:
DELETE FROM 表名 [WHERE条件];

6、truncate语句
语法:
truncate table 表名;

注意二者区别:
    1)TRUNCATE语句删除后将重置自增列,表结构及其字段、约束、索引保持不变,如果需要保留标识计数值,要用delete语句
    如果需要删除表的定义和数据,释放表空间,需要使用drop table语句,delete语句的优势,是按照条件删除数据,其它两种是没有条件的
    2)truncat语句跟不带where条件的delete语句用法类似,均可删除表中的所有数据,但是truncate删除的效率高于delete(delete是按行删除)
    3)delete是dml语句的一种,是带事务的,只有事务提交才可以生效,并且可以出发对应的触发器Trigger
    但是truncat和drop是自带事务的,操作后立即生效。不会触发trigger(触发器)

7、建表及插入数据语句:
drop table if exists students;
create table students(
id bigint(10) not null auto_increment comment ‘默认id’,
stu_no bigint(20) not null comment ‘学号’,
stu_name varchar(30) not null comment ‘姓名’,
login_pwd varchar(32) not null default ‘123’ comment ‘密码’,
sex char(2) not null default ‘男’ comment ‘性别’,
mobile_no varchar(11) default null comment ‘手机号’,
grade_id int(4) default null comment ‘年级’,
email varchar(50) default null comment ‘邮箱’,
birth_day datetime not null comment ‘出生日期’,
reg_time timestamp default current_timestamp comment ‘注册日期’,
idcard varchar(18) default null comment ‘身份证号’,
address varchar(200) default null comment ‘地址’,
primary key(id),
unique key(stu_no)
)engine=InnoDB auto_increment=2 default charset=utf8 comment ‘学生表’;

insert into students(stu_no,stu_name,mobile_no,birth_day)
values('172312','Tom','13223432423','1989-09-07');

insert into students 
values(3,'172313','Rosi','111','女','13334567890',
1,'[email protected]','1988-09-06',now(),'123123','江苏南京');

insert into students(stu_no,stu_name,mobile_no,birth_day)
values('172314','Jack','13223432424','1989-08-07'),
('172315','King','13223432425','1989-07-07'),
('172316','Abel','13223432426','1989-05-07'),
('172317','Wendi','13223432427','1989-06-07');

drop table if exists grade;
create table grade(
    grade_id int(4) not null comment '年级编号',
    grade_name varchar(50) not null comment '年级名称',
    primary key(grade_id)
)engine=InnoDB default charset=utf8 comment '年级表';

drop table if exists result;
create table result(
    stu_no bigint(20) not null comment '学号',
    subj_no int(4) not null comment '课程编号',
    exam_date datetime not null comment '考试时间',
    stu_result int(4) not null comment '考试成绩' 
)engine=InnoDB default charset=utf8 comment '成绩表';

drop table if exists subjects;
create table subjects(
    subj_no int(4) not null auto_increment primary key comment '课程编号',
    subj_name varchar(50) not null comment '课程名称',
    class_hour int(4) not null comment '学时',
    grade_id int(4) not null comment '年级编号' 
)engine=InnoDB default charset=utf8 comment '课程表';


alter table result add unique key uk_result(stu_no, subj_no, exam_date);

insert into `students` (`stu_no`, `stu_name`,`login_pwd`, `sex`, `grade_id`, `mobile_no`, `address`, `birth_day`, `email`, `idcard`) 
values('190001','蜘蛛侠','123','男','1','13645667783','南京市建邺区','1990-09-08',NULL,NULL),
('190002','钢铁侠','123','男','1','13645667883','南京市江宁区','1991-09-08',NULL,NULL),
('190003','闪电侠','123','男','1','13645661783','南京市栖霞区','1992-09-08',NULL,NULL),
('190004','超人','123','男','1','13645667703','南京市白下区','1993-09-08',NULL,NULL),
('190005','神奇女侠','123','女','1','13645657783','南京市玄武区','1994-09-08',NULL,NULL),
('190006','黑寡妇','123','女','1','13645664483','南京市雨花区','1995-09-08',NULL,NULL),
('190007','雷神','123','男','1','13645663383','南京市溧水区','1996-09-08',NULL,NULL),
('190008','海王','123','男','1','13645662283','南京市高淳区','1997-09-08',NULL,NULL),
('190009','蝙蝠侠','123','男','1','13645661183','南京市鼓楼区','1998-09-08',NULL,NULL),
('190010','沙赞','123','男','1','13645669983','南京市浦口区','1999-09-08',NULL,NULL);
select * from students;

insert into `result` (`stu_no`, `subj_no`, `exam_date`, `stu_result`) 
values('190001','1','2019-05-26 00:00:00','71'),
('190002','1','2019-05-26 00:00:00','60'),
('190003','1','2019-05-26 00:00:00','46'),
('190004','1','2019-05-26 00:00:00','80'),
('190005','1','2019-05-26 00:00:00','87'),
('190006','1','2019-05-26 00:00:00','73'),
('190007','1','2019-05-26 00:00:00','71'),
('190008','1','2019-05-26 00:00:00','95'),
('190009','1','2019-05-26 00:00:00','98'),
('190010','1','2019-05-26 00:00:00','55');

8、查询
语法:
SELECT <列名|表达式|函数|常量>
FROM <表名>
[WHERE <查询条件表达式>]
[ORDER BY <排序的列名>[ASC或DESC]];

查询全部列:
    select * from 表 [where条件]

查询部分列:
    select 列名,列名 from 表 [where 条件]

列的别名:
    select 列1 as 别名,列2 as 别名。。。 from 表 [where 条件]
    注意:as是可以省略的,别名可以加引号,加引号代表内容是一个整体

9、聚合函数(多行函数,组函数)
avg() 求平均值
count() 计数 有多少行就返回对应的行数,用法:count(1),count(2),count(*)都可以,但是如果是count(列),会忽略空值
max() 最大值,
max() 最小值,
sum() 求和
注意:
其中avg和sum是针对数值有效,max,min是针对所有数据类型有效,会忽略空值

10、字符串函数:
CONCAT(str1, str1…strn) 字符串连接
select CONCAT(‘hello’,‘world’) from dual;
INSERT(str, os,len, ewstr) 字符串替换 SELECT INSERT( ‘这是SQL Server数据库’, 3,10,‘MySQL’); 返回:这是MySQL数据库
lower(str) 转换小写
upper(str) 转换大写
select LOWER(‘MYSQL’),UPPER(‘mysql’) from dual;
SUBSTRING (str,num,len) 字符串截取
select SUBSTR(‘helloworld’,4) from dual;
select SUBSTRING(‘helloworld’,4,3) from dual;

length-返回字符长度(字节数)
replace-字符替换
    select LENGTH(stu_name) from students;
    select REPLACE('abhdefghh','h','k') from dual;
    select TRIM('h' FROM 'habhabh') from dual;

11、日期函数:
CURDATE() 获取当前日期
SELECT CURDATE() from dual;
返回:2016-08-08
CURTIME() 获取当前时间
SELECT CURTIME() from dual;
返回:19:19:26
NOW() 获取当前日期和时间
SELECT NOW() from dual;
返回:2016-08-08 19:19:26
WEEK(date) 返回日期date为一年中的第几周
SELECT WEEK(NOW()) from dual;
返回:26
YEAR(date) 返回日期date的年份
SELECT YEAR(NOW()) from dual;
返回:2016
HOUR(time) 返回时间time的小时值
SELECT HOUR(NOW()) from dual;
返回:9
MINUTE(time) 返回时间time的分钟值
SELECT MINUTE(NOW()) from dual;
返回:43
DATEDIFF(date1,date2) 返回日期参数date1和date2之间相隔的天数
SELECT DATEDIFF(NOW(), ‘2008-8-8’) from dual;
返回:2881
ADDDATE(date,n) 计算日期参数date加上n天后的日期
SELECT ADDDATE(NOW(),5) from dual;
返回:2016-09-02 09:37:07

#日期格式化,mysql date_format oracle to_char
select now() from dual;
select DATE_FORMAT(now(),'%Y年%m月%d日 %H:%i:%s') from dual;

12、数值函数
round(x)-四舍五入
truncate(x)-截断
ceil(x)-大于等于x的最小整数
floor(x)-小于等于x的最大整数
rand-0-1的随机数(0<=v<1.0)
示例:
# 注意第二个参数的正负含义,以小数点为分界点,左边为负,右边为正
select ceil(234.56),floor(234.56) from dual;
select round(234.56,1),round(234.56,-1) from dual;
select truncate(234.56,1),truncate(234.56,-1) from dual;

    select rand() from dual;
    #100以内的随机数
    select ceil(rand()*100) from dual;

13、排序:
ORDER BY子句实现按一定顺序显示查询结果
注意:order by 不一定要跟where子句,默认asc升序,desc降序

14、limit用法
语法:
SELECT <字段名列表>
FROM <表名或视图>
[WHERE <查询条件>]
[GROUP BY <分组的字段名>]
[ORDER BY <排序的列名>[ASC 或 DESC]]
[LIMIT [位置偏移量,]行数];
注意:位置偏移量是从0开始的,行数是展示的条数,不是第几行

    示例:
        查询所有年级编号为1的学员信息,按学号升序排序
        显示前4条记录
        每页4条,显示第2页,即从第5条记录开始显示4条数据

        select * from result
        order by stu_no desc
        limit 4;
        #limit 4,4

15、子查询:
语法:
SELECT … FROM 表1 WHERE 字段1 比较运算符(子查询),比较运算符是单行运算符
将子查询和比较运算符联合使用,必须保证子查询返回的值不能多于一个

示例:
    select stu_name,birth_day,sex,address from students s
    where s.birth_day > (
        select birth_day from students where stu_name = '神奇女侠'
    );

    SELECT MAX(`stu_result`)  AS 最高分,
                   MIN(`stu_result`) AS 最低分
    FROM `result`
    WHERE `subj_no`=
        (SELECT `subj_no` FROM `subjects` 
          WHERE `subj_name`='Java' ) AND
          `exam_date`=(SELECT MAX(`exam_date`) FROM `result` 
             WHERE `subj_no`=(SELECT `subj_no` FROM `subjects` 
             WHERE `subj_name`='Java'));
in的用法
    示例:
        select * from students where stu_no not in (
        select stu_no from result where stu_result = 60 and subj_no = 
        (select subj_no from subjects where subj_name = 'Java'))

like用法:
    select * from students where email like '_bc%';


分组和分组数据过滤

    select year(birth_day),count(1),max(length(stu_name))
    from students
    group by year(birth_day)
    having count(1) >= 2
闲聊时刻

10年短信公司,互联网100强企业!主营业务:短信(国内和国际)App H5一键免密登录,防薅羊毛接口,图片OCR,空号检测,活跃号检测,人证核验,活体检测,高防ddos攻击等等200多个企业服务接口!需要的联系他13592366783 官方链接:https://zz.253.com/v5.html#/register?uid=1953

自己公司需求 偶然间 用了一家第三方接口供应商,产品应有尽有,很齐全,对接文档非常详细,彼此都很节约时间,主要非常稳定,包括服务方面很给力,有兴趣的博友,可以联系他,算是对合作伙伴的支持了


你可能感兴趣的:(sql)