博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQL DML 数据操纵语句
阅读量:6173 次
发布时间:2019-06-21

本文共 19486 字,大约阅读时间需要 64 分钟。

前言

  • DML(Data Manipulation Language)语句:数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性。常用的语句关键字主要包括 insert、delete、update 和 select 等。

  • 常用约束类型

    约束类型 解释
    not null 非空约束,设定的内容在添加数据的时候不能是 null 的
    unique 唯一约束,值是唯一的
    primary key 主键约束,非空唯一
    auto_increment 主键自增约束,主键为数值型
    foreign key 外键约束,B 表使用 A 表的主键
  • 常用 where 查询条件

    where 条件 解释
    > < <= >= <> 大于、小于、大于(小于)等于、不等于
    between...and... 在某一区间,闭区间,效果同 and
    in(set) 在 in 列表中的值,如 in(100, 200),效果同 or
    like 通配符 模糊查询:% 匹配多个字符,如 first_name like "a%";_ 匹配一个字符,如 first_name like "a_"。
    is null 为空
    is not null 不为空
    and 同时成立
    or 任一成立
    not 不成立,如 where not(salary > 100);
  • 常用聚合查询条件

    统计函数 解释
    count() 求总数
    avg() 求平均数
    sum() 求和
    max() 求最大值
    min() 求最小值

1、DML 插入记录语句

  • 含可空字段、非空但是含有默认值的字段、自增字段,可以不用在 insert 后的字段列表里面出现,values 后面只写对应字段名称的 value,这些没有写的字段可以自动设置为 NULL、默认值、自增的下一个数字。

  • 1)插入单条记录

    # 插入单条记录,插入到指定列# insert into     表名     (列名1, 列名2, ...)   values     (值1, 值2, ...);> insert into student (name, age, class) values ("xiao bai", 18, "one");    Query OK, 1 row affected (0.09 sec)
    # 插入单条记录,插入到所有列# insert into     表名   values     (值1, 值2, ...);> insert into student values (2, "li si", 20, 90, "two", "aaaaaaaa");    Query OK, 1 row affected (0.04 sec)
  • 2)插入多条记录

    # 插入多条记录,插入到指定列# insert into     表名     (列名1, 列名2, ...)   values     (值1, 值2, ...),     (值1, 值2, ...),     ...;> insert into student (name, age, class) values ("zhang san", 18, "one"), ("li si", 19, "one");    Query OK, 2 rows affected (0.03 sec)    Records: 2  Duplicates: 0  Warnings: 0
    # 插入多条记录,插入到所有列# insert into     表名   values     (值1, 值2, ...),     (值1, 值2, ...),     ...;> insert into student values (5, "zhang san", 20, 90, "two", "aaaaaaaa"), (6, "li si", 21, 92, "two", "bbbbbbbb");    Query OK, 2 rows affected (0.08 sec)    Records: 2  Duplicates: 0  Warnings: 0

2、DML 删除记录语句

  • delete 一条一条删除,不清空 auto_increment 记录数,truncate 直接将表删除重建表,清空 auto_increment 记录数。
  • 不论时单表还是多表,不加 where 条件将会把表的所有记录删除。

  • 1)删除单个表中的记录

    # 删除单个表中的记录,删除所有表记录# delete from 表名;> delete from student;    Query OK, 5 rows affected (0.08 sec)
    # 删除单个表中的记录,删除满足条件的表记录# delete from 表名 where 条件;> delete from student where no = 5;    Query OK, 1 row affected (0.11 sec)
    # 删除单个表中的记录,删除所有表记录# truncate table 表名;> truncate table student;    Query OK, 0 rows affected (0.08 sec)
  • 2)删除多个表中的记录

    # 删除多个表中的记录,如果 from 后面的表用别名,delete 后面也要用相应的别名# delete     表名1,     表名2,     ...   from     表名1,     表名2,     ...  [where 条件];> delete    a, b  from    emp a, dept b  where    a.dept.no = b.deptno and a.deptno = 3;    Query OK, 2 rows affected (0.04 sec)

3、DML 更新记录语句

  • 1)更新单个表中的记录

    # 更新单个表中的记录,所有指定列记录# update 表名 set 字段名 = 值, 字段名 = 值;> update student set age = 18;    Query OK, 4 rows affected (0.02 sec)    Rows matched: 6  Changed: 4  Warnings: 0
    # 更新单个表中的记录,满足条件的指定列记录# update 表名 set 字段名 = 值, 字段名 = 值 where 条件;> update student set age = 19 where class = "two";    Query OK, 3 rows affected (0.02 sec)    Rows matched: 3  Changed: 3  Warnings: 0
  • 2)更新多个表中的记录

    # 更新多个表中的记录# update     表名1,     表名2,     ...   set     表名1.字段名1 = 值,     表名1.字段名2 = 值,    表名2.字段名1 = 值,    表名2.字段名2 = 值,    ...  [where 条件];> update     emp a, dept b  set     a.sal = a.sal * b.deptno,    b.deptname = a.ename  where    a.deptno = b.deptno;    Query OK, 3 rows affected (0.04 sec)    Rows matched: 5  Changed: 3  Warnings: 0
    • 多表的更新语法更多的用在根据一个表的字段来动态的更新另外一个表的字段。

4、DML 查询记录语句

4.1 查询单表记录

  • 1)简单查询

    # 查询单表记录,查询所有数据# select * from 表名;> select * from zhangwu;    +----+-----------------+-------+    | id | name            | money |    +----+-----------------+-------+    |  1 | chifanzhichu    |   247 |    |  2 | gongzishouru    | 12345 |    |  3 | fuzhuangzhichu  |  1000 |    |  4 | chifanzhichu    |   325 |    |  5 | gupiaoshouru    |  8000 |    |  6 | damajiangzhichu |  8000 |    |  7 | NULL            |  5000 |    +----+-----------------+-------+    7 rows in set (0.00 sec)
    # 查询单表记录,查询指定字段记录# select 字段1, 字段2, ... from 表名;> select id, name from zhangwu;    +----+-----------------+    | id | name            |    +----+-----------------+    |  1 | chifanzhichu    |    |  2 | gongzishouru    |    |  3 | fuzhuangzhichu  |    |  4 | chifanzhichu    |    |  5 | gupiaoshouru    |    |  6 | damajiangzhichu |    |  7 | NULL            |    +----+-----------------+    7 rows in set (0.00 sec)
  • 2)去重查询

    # 查询单表记录,去除重复记录# select distinct 字段名 from 表名;> select distinct money from zhangwu;    +-------+    | money |    +-------+    |   247 |    | 12345 |    |  1000 |    |   325 |    |  8000 |    |  5000 |    +-------+    6 rows in set (0.00 sec)
  • 3)条件查询

    # 查询单表记录,查询所有满足条件的记录# select * from 表名 where 条件;> select * from zhangwu where money >= 8000;    +----+-----------------+-------+    | id | name            | money |    +----+-----------------+-------+    |  2 | gongzishouru    | 12345 |    |  5 | gupiaoshouru    |  8000 |    |  6 | damajiangzhichu |  8000 |    +----+-----------------+-------+    3 rows in set (0.00 sec)
  • 4)别名查询

    • 使用 as 关键字标示别名,可省略。
    # 查询单表记录,表别名查询# select 字段名 from 表名 [as] 别名;> select name from zhangwu as zw;    +-----------------+    | name            |    +-----------------+    | chifanzhichu    |    | gongzishouru    |    | fuzhuangzhichu  |    | chifanzhichu    |    | gupiaoshouru    |    | damajiangzhichu |    | NULL            |    +-----------------+    7 rows in set (0.00 sec)
    # 查询单表记录,列别名查询# select 字段名 [as] 别名 from 表名;> select name as na from zhangwu;    +-----------------+    | na              |    +-----------------+    | chifanzhichu    |    | gongzishouru    |    | fuzhuangzhichu  |    | chifanzhichu    |    | gupiaoshouru    |    | damajiangzhichu |    | NULL            |    +-----------------+    7 rows in set (0.00 sec)
  • 5)列运算查询

    • 可以直接对列查询的结果进行运算。
    # 查询单表记录,列运算查询# select 字段名(列运算) from 表名;> select money + 10000 from zhangwu;    +---------------+    | money + 10000 |    +---------------+    |         10247 |    |         22345 |    |         11000 |    |         10325 |    |         18000 |    |         18000 |    |         15000 |    +---------------+    7 rows in set (0.00 sec)
  • 6)排序查询

    • 排序方式:asc 升序(默认,可省略),desc 降序,排序需放在 where 条件之后。
    # 查询单表记录,单列排序查询# select 字段名 from 表名 [where 条件] order by 列名 排序方式;> select     *  from     zhangwu   where     money > 1000   order by     money asc;    +----+-----------------+-------+    | id | name            | money |    +----+-----------------+-------+    |  7 | NULL            |  5000 |    |  5 | gupiaoshouru    |  8000 |    |  6 | damajiangzhichu |  8000 |    |  2 | gongzishouru    | 12345 |    +----+-----------------+-------+    4 rows in set (0.00 sec)
    # 查询单表记录,多列排序查询# select 字段名 from 表名 [where 条件] order by 列名 排序方式, 列名 排序方式, ...;> select     *  from     zhangwu   where     money > 1000   order by     money asc, id desc;    +----+-----------------+-------+    | id | name            | money |    +----+-----------------+-------+    |  7 | NULL            |  5000 |    |  6 | damajiangzhichu |  8000 |    |  5 | gupiaoshouru    |  8000 |    |  2 | gongzishouru    | 12345 |    +----+-----------------+-------+    4 rows in set (0.00 sec)
  • 7)限制查询

    • limit:只获取查询结果中从起始偏移量开始的指定行数的记录。
    • limit 属于 MySQL 扩展后的语法,在其它数据库上并不能通用。
    # 查询单表记录,限制查询# select 字段名 from 表名 [where 条件] [order by 列名 排序方式] limit [起始偏移量] 获取的行数> select     *  from     zhangwu   where     money > 1000   order by     money asc, id desc  limit    3;    +----+-----------------+-------+    | id | name            | money |    +----+-----------------+-------+    |  7 | NULL            |  5000 |    |  6 | damajiangzhichu |  8000 |    |  5 | gupiaoshouru    |  8000 |    +----+-----------------+-------+    3 rows in set (0.01 sec)
  • 8)聚合查询

    # 查询单表记录,求总数、统计# select count(字段名) from 表名;> select count(id) from zhangwu;    +-----------+    | count(id) |    +-----------+    |         7 |    +-----------+    1 row in set (0.00 sec)
    # 查询单表记录,求和# select sum(字段名) from 表名;> select sum(money) from zhangwu;    +------------+    | sum(money) |    +------------+    |      34917 |    +------------+    1 row in set (0.00 sec)
    # 查询单表记录,求平均数# select avg(字段名) from 表名;> select avg(money) from zhangwu;    +-------------------+    | avg(money)        |    +-------------------+    | 4988.142857142857 |    +-------------------+    1 row in set (0.00 sec)
    # 查询单表记录,求最大值# select max(字段名) from 表名;> select max(money) from zhangwu;    +------------+    | max(money) |    +------------+    |      12345 |    +------------+    1 row in set (0.01 sec)
    # 查询单表记录,求最小值# select min(字段名) from 表名;> select min(money) from zhangwu;    +------------+    | min(money) |    +------------+    |        247 |    +------------+    1 row in set (0.00 sec)
  • 9)分组查询

    • having 是对分组后的结果进行条件过滤,而 where 是在分组前就对记录进行过滤。
    • 如果逻辑允许,尽可能的使用 where 先过滤记录,因为这样结果集减小,将对聚合的效率大大提高,最后再根据逻辑看是否用 having 进行再过滤。
    # 查询单表记录,分组查询# select     字段名   from     表名  [where 条件]   group by     分组字段名   [order by 排序字段名 排序方式];> select class, count(no), avg(score) from student group by class;    +-------+-----------+------------+    | class | count(no) | avg(score) |    +-------+-----------+------------+    | one   |         3 |    81.6667 |    | two   |         2 |    77.5000 |    | three |         2 |    83.0000 |    +-------+-----------+------------+    3 rows in set (0.00 sec)
    # 查询单表记录,分组后过滤查询# select     字段名   from     表名  [where 条件]   group by     分组字段名   having     分组后的过滤条件  [order by 排序字段名 排序方式];> select class, count(no), avg(score) from student group by class having avg(score) >= 80;    +-------+-----------+------------+    | class | count(no) | avg(score) |    +-------+-----------+------------+    | one   |         3 |    81.6667 |    | three |         2 |    83.0000 |    +-------+-----------+------------+    2 rows in set (0.00 sec)
    # 查询单表记录,分组后汇总查询,对分类后的结果进行再汇总# select     字段名   from     表名  [where 条件]   group by     分组字段名   with rollup   [order by 排序字段名 排序方式];> select class, count(no), avg(score) from student group by class with rollup;    +-------+-----------+------------+    | class | count(no) | avg(score) |    +-------+-----------+------------+    | one   |         3 |    81.6667 |    | three |         2 |    77.5000 |    | two   |         2 |    83.0000 |    | NULL  |         7 |   242.1667 |    +-------+-----------+------------+    4 rows in set (0.00 sec)
  • 10)子查询

    • 某些情况下,当进行查询的时候,需要的条件是另外一个 select 语句的结果,这个时候,就要用到子查询。
    • 用于子查询的关键字主要包括 in、not in、=、!=、exists、not exists、any、all 等。
    • 子查询,理论上可以出现在任意位置,在 where 和 from 子句中较多。
    • where 子查询一般返回单行单列、单行多列、多行单列(in、any、all)的数据,from 子查询一般返回多行多列的数据。

    • where 子查询

    # 查询单表记录,where 单行单列子查询# select 字段名 from 表名 where 条件(子查询语句);> select     *  from     student   where     score > (select                score              from                student              where                name = "xiao bai"             )  order by score asc;    +----+-----------+------+-------+-------+----------+    | no | name      | age  | score | class | address  |    +----+-----------+------+-------+-------+----------+    |  1 | xiao hei  |   18 |    80 | one   | NULL     |    |  6 | li si     |   19 |    80 | two   | bbbbbbbb |    |  3 | zhang san |   18 |    95 | one   | NULL     |    +----+-----------+------+-------+-------+----------+    3 rows in set (0.00 sec)
    # 查询单表记录,where 单行多列子查询# select 字段名 from 表名 where 条件(子查询语句);> select     *  from     student   where     (age, class) = (select                       age, class                     from                       student                     where                       name = "zhang san"                   )  order by score asc;    +----+-----------+------+-------+-------+---------+    | no | name      | age  | score | class | address |    +----+-----------+------+-------+-------+---------+    |  1 | xiao hei  |   18 |    80 | one   | NULL    |    |  3 | zhang san |   18 |    95 | one   | NULL    |    |  4 | wang wu   |   18 |    70 | one   | NULL    |    +----+-----------+------+-------+-------+---------+    3 rows in set (0.00 sec)
    • where in 子查询
    # 查询单表记录,where 多行单列 in 子查询,与普通的 in 条件类似,如果子查询记录数唯一,还可以使用 = 代替 in# select 字段名 from 表名 where 条件(in 子查询语句);> select     *  from     student   where     age in (select               age             from               student             where               class = "one"           )  order by age asc;    +----+-----------+------+-------+-------+----------+    | no | name      | age  | score | class | address  |    +----+-----------+------+-------+-------+----------+    |  4 | wang wu   |   18 |    70 | one   | NULL     |    |  1 | xiao hei  |   18 |    80 | one   | NULL     |    |  3 | zhang san |   19 |    95 | one   | NULL     |    |  6 | li si     |   19 |    80 | two   | bbbbbbbb |    |  7 | xiao bai  |   19 |    79 | three | NULL     |    |  2 | da bai    |   19 |    75 | two   | aaaaaaaa |    +----+-----------+------+-------+-------+----------+    6 rows in set (0.00 sec)
    • where any 子查询
    # 查询单表记录,where 多行单列 =any 子查询,与 in 子查询一样# select 字段名 from 表名 where 条件(=any 子查询语句);> select     *  from     student   where     age = any (select                  age                from                  student                where                  class = "one"              )  order by age asc;    +----+-----------+------+-------+-------+----------+    | no | name      | age  | score | class | address  |    +----+-----------+------+-------+-------+----------+    |  4 | wang wu   |   18 |    70 | one   | NULL     |    |  1 | xiao hei  |   18 |    80 | one   | NULL     |    |  3 | zhang san |   19 |    95 | one   | NULL     |    |  6 | li si     |   19 |    80 | two   | bbbbbbbb |    |  7 | xiao bai  |   19 |    79 | three | NULL     |    |  2 | da bai    |   19 |    75 | two   | aaaaaaaa |    +----+-----------+------+-------+-------+----------+    6 rows in set (0.01 sec)
    # 查询单表记录,where 多行单列 >any 子查询,大于最小值# select 字段名 from 表名 where 条件(>any 子查询语句);> select     *  from     student   where     age > any (select                  age                from                  student                where                  class = "one"              )  order by age asc;    +----+-----------+------+-------+-------+----------+    | no | name      | age  | score | class | address  |    +----+-----------+------+-------+-------+----------+    |  2 | da bai    |   19 |    75 | two   | aaaaaaaa |    |  3 | zhang san |   19 |    95 | one   | NULL     |    |  6 | li si     |   19 |    80 | two   | bbbbbbbb |    |  7 | xiao bai  |   19 |    79 | three | NULL     |    |  5 | ma liu    |   20 |    78 | three | NULL     |    +----+-----------+------+-------+-------+----------+    5 rows in set (0.00 sec)
    # 查询单表记录,where 多行单列 
    select * from student where age < any (select age from student where class = "one" ) order by age asc; +----+----------+------+-------+-------+---------+ | no | name | age | score | class | address | +----+----------+------+-------+-------+---------+ | 1 | xiao hei | 18 | 80 | one | NULL | | 4 | wang wu | 18 | 70 | one | NULL | +----+----------+------+-------+-------+---------+ 2 rows in set (0.00 sec)
    • where all 子查询
    # 查询单表记录,where 多行单列 >all 子查询,大于最大值# select 字段名 from 表名 where 条件(>all 子查询语句);> select     *  from     student   where     age > all (select                  age                from                  student                where                  class = "one"              )  order by age asc;    +----+--------+------+-------+-------+---------+    | no | name   | age  | score | class | address |    +----+--------+------+-------+-------+---------+    |  5 | ma liu |   20 |    78 | three | NULL    |    +----+--------+------+-------+-------+---------+    1 row in set (0.00 sec)
    # 查询单表记录,where 多行单列 
    select * from student where age < all (select age from student where class = "one" ) order by age asc; +----+----------+------+-------+-------+---------+ | no | name | age | score | class | address | +----+----------+------+-------+-------+---------+ | 7 | xiao bai | 17 | 79 | three | NULL | +----+----------+------+-------+-------+---------+ 1 row in set (0.00 sec)
    • from 子查询
    # 查询单表记录,from 多行多列子查询,一般当作一张临时表的方式来处理# select 字段名 from 表名1 内/外连接表子查询语句;> select     B.bno, B.bname, B.bano, C.aname   from     B, (         select ano, aname, loc from A where ano < 2       ) C  where     B.bano = C.ano;    +-----+----------+------+-----------+    | bno | bname    | bano | aname     |    +-----+----------+------+-----------+    |   0 | zhangsan |    0 | 研发部    |    +-----+----------+------+-----------+    1 row in set (0.00 sec)

4.2 查询多表记录

  • 当需要同时显示多个表中的字段时,就可以用表连接来实现这样的功能。
  • 从大体上分,表连接分为内连接和外连接,它们之间最主要的区别是,内连接仅选出两张表中互相匹配的记录,而外连接会选出其它不匹配的记录。

  • 1)多表联合查询

    # 查询多表记录,多表联合查询,一定要有表于表之间的关联字段# select 字段名 from 表名1, 表名2 where 关联条件;> select     B.bno, B.bname, B.bano, A.aname   from     B, A   where     B.bano = A.ano;     +-----+----------+------+-----------+    | bno | bname    | bano | aname     |    +-----+----------+------+-----------+    |   0 | zhangsan |    0 | 研发部     |    |   1 | lisi     |    2 | 销售部     |    +-----+----------+------+-----------+    2 rows in set (0.00 sec)
  • 2)内联查询

    # 查询多表记录,内连接查询# select 字段名 from 表名1 inner join 表名2 on 关联条件;> select     B.bno, B.bname, B.bano, A.aname   from     B   inner join     A   on     B.bano = A.ano;    +-----+----------+------+-----------+    | bno | bname    | bano | aname     |    +-----+----------+------+-----------+    |   0 | zhangsan |    0 | 研发部     |    |   1 | lisi     |    2 | 销售部     |    +-----+----------+------+-----------+    2 rows in set (0.00 sec)
  • 3)外联查询

    # 查询多表记录,左外连接查询,包含所有的左表中的记录甚至是右表中没有和它匹配的记录# select 字段名 from 表名1 left outer join 表名2 on 关联条件;> select     B.bno, B.bname, B.bano, A.aname  from     B   left outer join     A   on     B.bano = A.ano;    +-----+----------+------+-----------+    | bno | bname    | bano | aname     |    +-----+----------+------+-----------+    |   0 | zhangsan |    0 | 研发部     |    |   1 | lisi     |    2 | 销售部     |    |   2 | wangwu   | NULL | NULL      |    +-----+----------+------+-----------+    3 rows in set (0.00 sec)
    # 查询多表记录,右外连接查询,包含所有的右表中的记录甚至是左表中没有和它匹配的记录# select 字段名 from 表名1 left outer join 表名2 on 关联条件;> select     B.bno, B.bname, B.bano, A.aname  from     B   right outer join     A   on     B.bano = A.ano  order by    bno asc;    +------+----------+------+-----------+    | bno  | bname    | bano | aname     |    +------+----------+------+-----------+    | NULL | NULL     | NULL | 财务部     |    |    0 | zhangsan |    0 | 研发部     |    |    1 | lisi     |    2 | 销售部     |    +------+----------+------+-----------+    3 rows in set (0.00 sec)
    # 查询多表记录,全外连接查询,包含所有的左表和右表中的记录甚至是没有匹配的记录# MySQL 是不支持全外的连接的,这里给出的写法适合 Oracle 和 DB2# select 字段名 from 表名1 left outer join 表名2 on 关联条件;> select     B.bno, B.bname, B.bano, A.aname  from     B   full outer join     A   on     B.bano = A.ano  order by    bno asc;
  • 4)记录联合查询

    • 我们经常会碰到这样的应用,将两个表的数据按照一定的查询条件查询出来后,将结果合并到一起显示出来。
    • 这个时候,就需要用 union 和 union all 关键字来实现这样的功能。
    • union all 会把结果直接合并在一起,union 会将合并后的结果进行一次 distinct 去除重复的记录。
    # 查询多表记录,记录联合查询# select 字段名 from 表名1   union | union all  select 字段名 from 表名2;> select ano, aname, loc from A union all select bno, bname, bano from B;    +-----+-----------+------+    | ano | aname     | loc  |    +-----+-----------+------+    |   0 | 研发部     | aaaa |    |   1 | 财务部     | bbbb |    |   2 | 销售部     | cccc |    |   0 | zhangsan  | 0    |    |   1 | lisi      | 2    |    |   2 | wangwu    | NULL |    +-----+-----------+------+    6 rows in set (0.00 sec)

转载于:https://www.cnblogs.com/QianChia/p/9185074.html

你可能感兴趣的文章
修改下拉框的样式
查看>>
程序员之路-学习经验总结分享
查看>>
产业升级、政策助跑,中国能否在物流无人机领域干掉美国?
查看>>
Dubbo 3.0 预览版解读,支持 Filter 链的异步化
查看>>
Redis实践(十六)-内存管理
查看>>
「mysql优化专题」主从复制面试宝典!面试官都没你懂得多!(11)
查看>>
WPS for Linux 社区版 10.1.0.6758 发布
查看>>
使用阿里云接口进行银行卡四要素实名认证
查看>>
聊聊excel生成图片的几种方式
查看>>
20 万网络节点背后的数据创新应用
查看>>
理论 | 朴素贝叶斯模型算法研究与实例分析
查看>>
docker安装gitlab只需要3分钟
查看>>
Android菜鸟学习js笔记 一
查看>>
Java基础之SPI机制
查看>>
unzip --help帮助文件翻译
查看>>
C++ 模拟生产者与消费者模式等
查看>>
使用js控制滚动条的位置
查看>>
【Tornado源码阅读笔记】tornado.web.Application
查看>>
js计数器方法setInterval()、clearInterval()、setTimeout()和clearTimeout()
查看>>
最优化问题的解法 - 动态规划
查看>>