SQL语句之DML

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL语句之DML相关的知识,希望对你有一定的参考价值。

DML:Database Manipulate Language
DML include:select,delete,insert into,update
aka == also known as

  • select
执行顺序
start --> [from --> [where] --> [[group by] --> [having]] --> [order by]] --> select --> [limit] --> end
select select_list from tb_name where condition;
select查询类型
1)简单查询,单表查询
2)多表查询
3)子查询,嵌套查询

所有 select * from tb_name;
选择 select * from tb_name where condition;
投影 select [distinct] field1,filed2,... from tb_name;
[distinct]去除重复选项

单表查询
  • from子句,表示要查询的关系,表、多表、其他select语句
  • where子句 
逻辑关系操作符 
and
&&
or
||
not
!
条件判断操作符
>,<,=,<=>,between,in,like,rkike aka regexp,is null,is not null
<=> null safe euqal to;

example
mysql> select name,age,gender from students where not age>20 and not gender=‘M‘;
mysql> select name,age,gender from students where age between 20 and 25; 连续取值
mysql> select name,age from students where age in (19,25); 离散取值
mysql> select name from students where name like ‘L%‘;
mysql> select name from students where name like ‘Y____‘;
mysql> select name,age,gender from students where name rlike ‘^[YXN].*‘;

  • order by子句,排序
order by field_name [ASC|DESC]
mysql> select name,age from students order by age desc;

  • limit [offset,]count子句,限制显示的行数
mysql> select name as student_name,age as age_number from students order by age desc limit 2,4;

  • as 字段别名
mysql> select name as student_name,age as age_number from students order by age desc;

聚合:sum(),min(),max(),avg(),count()
having用于将group by的结果再次进行过滤
mysql> select cid1 as course,count(cid1) as total from students group by cid1;
mysql> select cid1 as course,count(cid1) as total from students group by cid1 having total>=2;

多表查询
连接:
  • 交叉连接:笛卡尔乘积,数据量大时不宜使用
  • 自然连接
  • 外连接
  左外连接:... LEFT JOIN ... ON ...
  右外连接: ... RIGHT JOIN ... ON ...
  • 自连接,一张表变成两张表

自然连接
mysql> select name,cname from students,courses where courses.cid=students.cid1;
mysql> select students.name,courses.cname from students,courses where courses.cid=students.cid1;标准写法
mysql> select s.name,c.cname from students as s,courses as c where c.cid=s.cid1; 表的别名

外连接
左外连接 mysql> select s.name,c.cname from students as s left join courses as c on c.cid=s.cid1;
右外连接 mysql> select s.name,c.cname from students as s right join courses as c on c.cid=s.cid1;

自连接
mysql> select s.name as student,t.name as teacher from students as s,students as t where t.sid=s.tid;

子查询
1)比较操作中使用子查询:子查询只能返回单个值;
mysql> select name,age from students where age>(select avg(age) from students);
2)IN(): 使用子查询;
mysql> select name from students where age in (select age from tutors);
3)在FROM中使用子查询,可改写为多条件查询

联合查询UNION,只做联合不做判断
mysql> (select name,age from students) union (select tname,age from tutors);
mysql> (select name,age from students) union (select tname,gender from tutors);

练习
1、挑选出courses表中没有被students中的CID2学习的课程的课程名称;
mysql> select cname from courses where cid not in (select distinct cid2 from students where cid2 is not null);
附加:挑选出没有教授任何课程的老师,每个老师及其所教授课程的对应关系在courses表中;
mysql> select tname from tutors where tutors.tid not in (select distinct courses.tid from courses );
        找出students表中CID1有两个或两个以上同学学习了的同一个门课程的课程名称;
mysql> select cname from courses where courses.cid in (select cid1 from students group by cid1 having count(cid1)>=2);
2、显示每一位老师及其所教授的课程;没有教授的课程的保持为NULL;
mysql> select tname,cname from tutors left join courses on tutors.tid=courses.tid;
3、显示每一个课程及其相关的老师,没有老师教授的课程将其老师显示为空;
mysql> select tname,cname from tutors right join courses on tutors.tid=courses.tid;
4、显示每位同学CID1课程的课程名及其讲授了相关课程的老师的名称;
mysql> select name,cname,tname from students,courses,tutors where students.cid1=courses.cid and courses.tid=tutors.tid;

view 视图 虚表  
    基于基表的存储下来的select查询语句

创建视图
CREATE VIEW view_name AS select_statement
    
mysql> create view information as select name,cname,tname from students,courses,tutors where students.cid1=courses.cid and courses.tid=tutors.tid;

删除视图
DROP VIEW view_name

说明:
由于每次查看视图都要执行select语句,由于视图没有索引,性能可能没有多少提升;但是物化视图(mysql不支持),查询速度快;同时,视图可以用在只想让用户查看某些字段,增加安全性的情况。

insert
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [(col_name,...){VALUES | VALUE} ({expr | DEFAULT},...),(...),... [ ON DUPLICATE KEY UPDATE col_name=expr [, col_name=expr] ... ]

Or:一次插入一行指定字段的数据
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name SET col_name={expr | DEFAULT}, ... [ ON DUPLICATE KEY UPDATE col_name=expr [, col_name=expr] ... ]
example
mysql> insert into students set name=‘Agan‘,age=26,gender=‘M‘,cid1=8,cid2 =7,tid=6,createtime=‘2016-05-26 18:01:30‘;

Or:将查询出来的数据加入表中
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [(col_name,...)] SELECT ...[ ON DUPLICATE KEY UPDATE col_name=expr[, col_name=expr] ... ]
mysql> insert into tutors (tname,gender,age) select name,gender,age from students where age > 10;

只显示最后插入的数据
mysql> select * from student order by sid desc limit 1,2;
mysql> select * from student order by sid desc limit 0,2;

显示计数器
mysql> select last_insert_id();

出现的问题:
使用 create table tb_name1 like tb_name2,若有auto_increment选项,则使用同一个计数器,两个表间的使用auto_increment字段的计数会累加

replace
用法和insert类似

  • delete
1)使用delete时,未使用where,可以禁止此操作;
2)计数器不变,在原来基础上继续计数
mysql> delete from student order by sid desc limit 10;

  • truncate table
TRUNCATE [TABLE] tbl_name
清空表并清空auto_increment计数器

  • update
UPDATE tb_name SET col1=..., col2=... WHERE






以上是关于SQL语句之DML的主要内容,如果未能解决你的问题,请参考以下文章

是选择 DML 还是 DDL?

binlog-rollback.pl 在线恢复update 和delete不加条件误操作sql

SQL语句之DWLDCL语句

oracle数据库之PL/SQL 流程控制语句

如何做SQL优化?优化SQL语句,提高SQL查询效率。Effective MySQL之SQL语句最优化

SQL之SELECT语句排序