03 表的操作以及单表查询

1. 修改、删除被关联字段

主表(父表)、从表(子表)

show create table 从表;		# 查看外键名称

create table t1(id int, pid int constraint 名字 foreign key(关联字段) reference 主表(被关联字段) ; 
# 创建外键时可以指定外键名称(不能创建后修改)

查看所有外键的名称的方法: 
select REFERENCED_TABLE_SCHEMA,REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME,table_name,CONSTRAINT_NAME from information_schema.key_column_usage;  
#包含我们创建外键的时候,mysql帮我们自动生成的外键名称。

删除外键关系

alter table 从表 drop foreign key 外键名称;

删除主表关联字段

alter table 主表 drop 关联字段名称;	# 删除外键关系后,才能删关联的字段

添加字段

alter table 表名 add 字段名称 数据类型 约束条件;

创建表后,再添加外键关系

alter table 从表 add foreign key(关联字段) reference 主表(被关联字段) ;

2. 级联

级联的模式:

严格模式(district),外键有强制约束效果,被关联字段不能随意删除和修改。

级联模式(cascade),外键有强制约束效果,被关联字段删除或者修改,关联字段的数据也会删除或者修改。

置空模式(set null),被关联字段删除时,关联它的字段数据会置换成null,不会删除。

外键约束有三种约束模式(都是针对父表的约束):

    模式一: district 严格约束(默认的 ),父表不能删除或者更新已经被子表数据引用的记录

    模式二:cascade 级联模式:父表的操作,对应的子表关联的数据也跟着操作 。

    模式三:set null:置空模式,父表操作之后,子表对应的数据(外键字段)也跟着被置空。

    通常的一个合理的约束模式是:删除的时候子表置空;更新的时候子表级联。

    指定模式的语法:foreign key(外键字段) references 父表(主键字段)on delete 模式 on update 模式;

    注意:删除置空的前提条件是 外键字段允许为空,不然外键会创建失败。

    外键虽然很强大,能够进行各种约束,但是外键的约束降低了数据的可控性和可拓展性。通常在实际开发时,很少使用外键来约束

alter table 从表 add foreign key(从表字段) reference 主表(主表字段) on delete cascade;
# 当删除主表数据的时候,从表中有关的数据都跟着删除

alter table 从表 add foreign key(从表字段) reference 主表(主表字段)on update cascade;
# 当主表的关系字段修改的时候,从表对应的关系字段的值也更着更新。

# 例如
constraint fk_t1_publish foreign key(pid) references publish(id) on delete cascade on update cascade;

3. 表详细操作

alter table 表名 + 操作

# 1.修改表名
alter table 表名 rename 新表名;

# 2.增加字段
alter table 表名 add 字段名 数据类型 约束条件
	first; #添加字段,并将其放在第一个字段的前面(开头)
	
	after;	 # after表示放在最后字段的后面(末尾)
#通过一个first和一个after就可以将新添加的字段放到表的任意字段位置。
                            
# 3.删除字段
alter table 表名 drop 字段名;

# 4.修改字段
alter table 表名 modify 字段名 新数据类型 约束条件;  
# 修改字段数据类型

alter table 表名 change 旧字段名 新字段名 新数据类型 约束条件;
# 既可以修改数据类型(也可不更改),又可以修改字段名字

4. 行记录操作

4.1 增加 insert

1. 插入完整数据(顺序插入)
    语法一:
    insert into 表名(字段1,字段2,字段3…字段n) values(值1,值2,值3…值n);  #指定字段来插入数据,插入的值要和你前面的字段相匹配

    语法二:
    insert into 表名 values (值1,值2,值3…值n); #不指定字段的话,就按照默认的几个字段来插入数据

2. 指定字段插入数据
    语法:
    insert into 表名(字段1,字段2,字段3…) values (值1,值2,值3…);

3. 插入多条记录
    语法:#插入多条记录用逗号来分隔
    insert into 表名 values
        (值1,值2,值3…值n),
        (值1,值2,值3…值n),
        (值1,值2,值3…值n);
        
4. 插入查询结果
    语法:
    insert into 表名(字段1,字段2,字段3…字段n) 
                  select (字段1,字段2,字段3…字段n) from 表2
                  where …; #将从表2里面查询出来的结果来插入到我们的表中,但是注意查询出来的数据要和我们前面指定的字段要对应好

4.2 修改(更新)update

update 表名 set 字段1=值1,字段2=值2 where 条件;

4.3 删除 delete

delete from 表名 where 条件;  # 删除指定条件字段的值

delete from 表名;	 # 删除所有的数据,但是不会重置自增字段的数字

truncate 表名;  # 全清空,可使自增字段重置

4.4 查询 select

分单表查询与多变查询

5. 单表查询

#查询数据的本质:mysql会到你本地的硬盘上找到对应的文件,然后打开文件,按照你的查询条件来找出你需要的数据。下面是完整的一个单表查询的语法

select * from,这个select * 指的是要查询所有字段的数据。

select distinct 字段1,字段2... from 库名.表名    #from后面是说从库的某个表中去找数据,mysql会去找到这个库对应的文件夹下去找到你表名对应的那个数据文件,找不到就直接报错了,找到了就继续后面的操作
                  where 条件;     #从表中找符合条件的数据记录,where后面跟的是你的查询条件
                  group by field(字段)   #分组
                  having 筛选      #过滤,过滤之后执行select后面的字段筛选,就是说我要确定一下需要哪个字段的数据,你查询的字段数据进行去重,然后在进行下面的操作
                  order by field(字段)   #将结果按照后面的字段进行排序
                  limit 限制条数    #将最后的结果加一个限制条数,就是说我要过滤或者说限制查询出来的数据记录的条数

5.1 关键字的执行优先级(重点)

重点中的重点:关键字的执行优先级
from
where
group by
having
select
distinct
order by
limit

步骤

1.找到表:from

  2.拿着where指定的约束条件,去文件/表中取出一条条记录

  3.将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组

  4.将分组的结果进行having过滤

  5.执行select

  6.去重

  7.将结果按条件排序:order by

  8.限制结果的显示条数

5.2 查询

select * from 表名;  # 查看全部,不推荐*,效率低
select 字段1,字段2 from 表名; 

select distinct 字段 from 表名;	 # 对查询出来的记录进行去重,如果对多个字段进行去重,会对数据重复少的字段去重
# distinct 前面不允许写字段

# 四则运算
select 字段运算 from 表名;  # 结果显示:运算字段的显示名字会变成运算表达式,例如:select salary*12 from empioyee;  字段名会显示 salary*12,不美观,
可以用 as + 新字段名 来指定。

# 自定义格式 字节规定查询结果的显示格式 concat()
select concat("姓名:",name, "年薪:",salary*12) as Salary from empioyee;
# 拼接字符串,放在一列内。

5.3 where约束

where语句中可以使用:

  1. 比较运算符:> 、< 、>=、 <= 、<> (不等于)、!=
  2. between 80 and 100 # 值在80到100之间
  3. in(80,90,100) # 值是80或90或100
  4. like 'egon%'
      pattern可以是%或_,
      %表示匹配任意多字符
      _表示匹配一个字符 可多写几个_
  5. 逻辑运算符:在多个条件直接可以使用逻辑运算符 and、or、not
#1:单条件查询
    SELECT name FROM employee
        WHERE post='sale';  #注意优先级,我们说where的优先级是不是比select要高啊,所以我们的顺序是先找到这个employee表,然后按照post='sale'的条件,然后去表里面select数据
        
#2:多条件查询
    SELECT name,salary FROM employee 
        WHERE post='teacher' AND salary>10000;

#3:关键字BETWEEN AND 写的是一个区间
    SELECT name,salary FROM employee 
        WHERE salary BETWEEN 10000 AND 20000; #就是salary>=10000 and salary<=20000的数据

    SELECT name,salary FROM employee 
        WHERE salary NOT BETWEEN 10000 AND 20000; #加个not,就是不在这个区间内,薪资小于10000的或者薪资大于20000的,注意没有等于,
    
#4:关键字IS NULL(判断某个字段是否为NULL不能用等号,需要用IS) 判断null只能用is
    SELECT name,post_comment FROM employee 
        WHERE post_comment IS NULL;

    SELECT name,post_comment FROM employee 
        WHERE post_comment IS NOT NULL;
        
    SELECT name,post_comment FROM employee 
        WHERE post_comment=''; 注意''是空字符串,不是null,两个是不同的东西,null是啥也没有,''是空的字符串的意思,是一种数据类型,null是另外一种数据类型
    ps:
        执行
        update employee set post_comment='' where id=2;
        再用上条查看,就会有结果了

#5:关键字IN集合查询
    SELECT name,salary FROM employee 
        WHERE salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ; #这样写是不是太麻烦了,写一大堆的or,下面我们用in这个简单的写法来搞
    
    SELECT name,salary FROM employee 
        WHERE salary IN (3000,3500,4000,9000) ;

    SELECT name,salary FROM employee 
        WHERE salary NOT IN (3000,3500,4000,9000) ;

#6:关键字LIKE模糊查询,模糊匹配,可以结合通配符来使用
    通配符’%’  #匹配任意所有字符
    SELECT * FROM employee 
            WHERE name LIKE 'eg%';

    通配符’_’  #匹配任意一个字符   
    SELECT * FROM employee 
            WHERE name LIKE 'al__'; #注意我这里写的两个_,用1个的话,匹配不到alex,因为al后面还有两个字符ex。

5.4 分组查询:group by

分组发生在where之后,即分组是基于where之后得到的记录而进行的。

分组指的是:将所有记录按照某个相同字段进行归类,比如针对员工信息表的职位分组,或者按照性别进行分组等。(字段是分组依据)

select * from 表名 group by 字段; #默认取分组后的每组第一条数据

# group by关键字与group_concat函数一起使用,可以显示组内某个字段的所有数据
select post,group_concat(name) from employee group by post; #例如,按照岗位分组,并查看组内所有成员名,通过逗号拼接在一起

# 聚合函数
select count(字段),其他字段 from 表名 group by 分组字段; 
# 统计分组后,每组个数

聚合函数:count、max、min、avg、sum等。

group by分组时后可以跟多个条件,那么这多个条件同时重复才算一组,用逗号隔开。

ONLY_FULL_GROUP_BY 模式下 :限制查询字段必须是分组依据所用的字段和聚合函数。(你select后面取的字段必须在你的group by后面的字段里面才行。)

5.5 having 分组后过滤

where优先级在group by 前面,因此分组后加条件需havind;

havind后面可以加聚合函数,where不行

select 字段,聚合函数(字段) from 表名 group by 字段 having 聚合函数

having与where区别:

having的语法格式和where是一模一样的,只不过having是在分组之后进行的进一步的过滤,where不能使用聚合函数,having是可以使用聚合函数的。
#!!!执行优先级从高到低:where > group by > having 
#1. Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数。
#2. Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段。

5.6 去重distinct

1.将查询的结果进行去重:select distinct post from employee; 

2.用distinct来返回不重复字段的条数(count(distinct id)),其原因是distinct只能返回他的目标字段,而无法返回其他字段,distinct 想写在其他字段后面需要配合聚合函数来写,否则只会取到第一条记录。

mysql> select count(distinct post) from employee;
+----------------------+
| count(distinct post) |
+----------------------+
|                    4 |
+----------------------+
1 row in set (0.00 sec)

5.7 查询排序 order by

默认升序,加 desc是降序。

select * from 表名 order by 字段 asc; #按照字段升序,asc可不写
select * from 表名 order by 字段 desc; #降序

# 多条件排序
select * from 表名 order by 字段1 asc, 字段2 desc;
# 按字段1升序排列,字段1中相同的数据,按照字段2降序排序

5.8 限制结果的显示条数 limit

网站的分页显示功能。默认初始位置为0。

select * from 表名 order by 字段 desc limit 0,5;
# 从第0开始查询,共5条

select * from 表名 order by 字段 desc limit 5,5;
# 从第5条开始查询,共5条

5.9 正则表达式查询

select * from 表名 where 字段 regexp '^a'; # ^a 是查询字段中所有a开头的数据

查看所有员工中名字是jin开头,n或者g结束的员工信息
select * from employee where name regexp '^jin.*[g|n]$';

补充:级联set null的用法和示例

mysql> create table tt2(id int primary key auto_increment,name char(10));

mysql> create table tt3(id int,pid int,foreign key(pid) references tt2(id) on delete set null);
Query OK, 0 rows affected (1.06 sec)

mysql> desc tt3;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
| pid   | int(11) | YES  | MUL | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.01 sec)

mysql> insert into tt2(name) values('xx1'),('xx2');
Query OK, 2 rows affected (0.14 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> insert into tt3 values(1,1),(2,1);
Query OK, 2 rows affected (0.12 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from tt3;
+------+------+
| id   | pid  |
+------+------+
|    1 |    1 |
|    2 |    1 |
+------+------+
2 rows in set (0.00 sec)

mysql> delete from tt2 where id = 1;
Query OK, 1 row affected (0.10 sec)

mysql> select * from tt3;
+------+------+
| id   | pid  |
+------+------+
|    1 | NULL |
|    2 | NULL |
+------+------+
2 rows in set (0.00 sec)

https://www.cnblogs.com/clschao/articles/9995531.html

原文地址:https://www.cnblogs.com/yzm1017/p/11455269.html