zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    UVA 10618 Tango Tango Insurrection
    UVA 10118 Free Candies
    HDU 1024 Max Sum Plus Plus
    POJ 1984 Navigation Nightmare
    CODEVS 3546 矩阵链乘法
    UVA 1625 Color Length
    UVA 1347 Tour
    UVA 437 The Tower of Babylon
    UVA 1622 Robot
    UVA127-"Accordian" Patience(模拟)
  • 原文地址:https://www.cnblogs.com/yzm1017/p/11455269.html
Copyright © 2011-2022 走看看