mysql基础知识

        当今是物联网时代,也是大数据的时代。所以数据的重要性,毋庸置疑。比起传统的文件管理系统,数据库管理系统有较小的数据冗余,程序与数据相对独立,数据更安全、可靠,数据的正确性得到保障,可以动态的管理数据库。

数据库管理系统的功能:

(1)数据定义

(2)数据处理

(3)数据安全

(4)数据备份

一、关系型数据库

       所谓的关系就是一张二维表。表中的行又称为记录,列称为属性、字段,主键是用于唯一确定一个记录的字段。关系数据库中一个重要的概念就是事务----多个操作被当做一个整体来对待。

实体-联系模型E-R

实体:实实在在存在并可以相互区分的客观事物或抽象事件

联系:数据之间的关联集合。

二、数据库的正规化分析

        设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要 求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。 目前关系数据库有六种范式。满足最低要求的范式是第一 范式(1NF),在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以 次类推。一般说来,数据库只需满足第三范式(3NF)即可。

1NF——范式的理解

        1NF是关系型数据库中的最基本要求,就是要求记录的属性是原子性,不可分,就是属性不能分,这是关系型数据库的基本要求,不满足这个就不能叫关系型数据库了

例如:

讲师  性别    班级    教室    代课时间       代课时间(开始,结束)
张三 Male  15级6班   102        30天        2018-09-30,2018-10-30
李四 Male  15级7班    106       30天        2018-09-30,2018-10-30
王五 male  15级8班    106       15天        2018-09-17,2018-10-02

上面的代课时间字段设计就不满足原子性,因为它可以再分的,开始时间和结束时间,需要按照下面来设计拆分:

讲师             性别           班级          教室         代课时间      开始                 结束

张三             Male         15级6班       102          30天          2018-09-30       2018-10-30
张三             Male        15级7班       106           30天           2018-09-30       2018-10-30
王五             male         15级7班       106          15天           2018-09-17       2018-10-02

2NF——范式的理解

       2NF是不能有部分依赖,部分依赖的前提条件是有组合主键,就是每条记录是需要一个主键的,这个主键可以是一个单独的属性,但也可以是组合主键,就是由记录的多个属性来唯一确定一条记录,那么只要出现了组合主键就可以产生部分依赖,部分依赖是组合主键出现的前提下,剩余的属性,不完全依赖于组合主键,也是部分依赖组合主键,比如该表的N条记录中由组合主键中的一条或者几条就可以确定剩余属性的属性,那么就可以说产生部分依赖,而在实际开发中,一般不采用组合主键,而是自己增加一个字段id自增长,作为主键,这样的单属性主键是不会产生部分依赖的!

例如:

讲师P           性别           班级P         教室         代课时间         开始             结束

张三             Male       15级6班          102         30天           2018-09-30      2018-10-30
张三             Male        15级7班         106         30天           2018-09-30      2018-10-30
王五             male        15级7班         106         15天           2018-09-17      2018-10-02

       上面的设计可以用讲师P,班级,两个字段作为组合主键,但是问题来了,那么后面的教室仅仅由班级字段(组合主键中的一条)就可以确定,即所谓教室部分依赖于组合主键,那么就不符合2NF

应该按照下面就行设计:

IDP       讲师            性别          班级         教室            代课时间       开始               结束
1         张三             Male       15级6班         102           30天         2018-09-30      2018-10-30
2         张三             Male       15级7班         106           30天         2018-09-30       2018-10-30 

可以看到仅仅增加一个主键IDP就不存在部分依赖了,这是实际项目中开发中常用的手段!

3NF——范式的理解

        不能出现传递依赖:就是主键,非主键1,非主键2三者之间不能出现传递依赖关系,如果出现由主键可以推出非主键1,然后由非主键1可以推出非主键2,那么主键与非主键2就产生了传递依赖关系,这就不满足三范式,通俗来讲,在一个表中,当然以一条记录为单位,主键和非主键之间可以产生父子关系,但是非主键之间是不能出现父子关系的!

例如:

IDP      讲师           性别           班级           教室      代课时间             开始               结束
1         张三          Male        15级6班           102        30天              2018-09-30        2018-10-30
2        张三           male        15级7班         106         30天              2018-09-30         2018-10-30
3        王五           male        15级7班         106         15天              2018-09-17         2018-10-02

上面的设计不满足3NF:

主键1--推出--->班级15级7班,班级15级7班-----推出---->教室102,这样给人的感觉,教室不是由主键IDP1直接推出的,好像由班级通过传递推出的;当然还存在

主键IDP---->讲师------>性别

这样的坏处就是会产生数据冗余,解决方案是把中间的代理抽出来作为另外一张表:

应该如下设计:

IDP     讲师          班级            代课时间               开始              结束
1         张三        15级6班        30天              2018-09-30      2018-10-30
2         张三        15级7班        30天              2018-09-30       2018-10-30
3         王五         15级7班       5天                2018-09-17         2018-10-02

 

讲师         性别
张三         male
王五       male

 

班级          教室

15.6            102

15.7             106

总结:数据库的设计可以先按照自己的想法设计一个"大表"出来,然后进行拆分成符合三范式的表,当然一般的规律的实体都单独作为一个表格

比如讲师实体,班级实体,代课关系实体,但是最大的问题是开始不知道哪些是实体,其实除了看得见的,其实说的清的可以描述的关系也可以作为一个实体

几个sql中重要的概念

约束:        constraint,表中的数据要遵守的限制

主键:       一个或多个字段的组合,填入的数据必须能在本表中唯一标识本行;必须提供数据,即NOT NULL,一个表只能存在一个

唯一键:   一个或多个字段的组合,填入的数据必须能在本表中唯一标识本行;允许为NULL,一个表可以存在多个

外键:       一个表中的某字段可填入的数据取决于另一个表的主键或唯一键已有的数据

索引:     将表中的一个或多个字段中的数据复制一份另存,并且此些需要按特定次序排序存储

关系运算:

                  选择:挑选出符合条件的行

                  投影:挑选出需要的字段 (列)

                  连接:表间字段的关联

三、安装MairaDB(通用二进制格式安装)

(1)从downloads.mariadb.org  下载所需版本的mariadb的二进制包 mariadb-10.3.9-linux-x86_64.tar.gz

(2)创建所需用户及组

[root@centos6 ~]# groupadd -g 27 -r mysql(-r:系统组)
[root@centos6 ~]# useradd -u 27 -r -g mysql -m -d /app/dbdata -s /sbin/nologin mysql(-r: 系统用户   -m : 创建家目录)

(3)准备数据目录/app/dbdata,建议做到lVM上,因为数据库需要动态管理,方便扩展

[root@centos6~]# fdisk /dev/sda(在分区的时候设置类型为8e)
[root@centos6 ~]# partx -a /dev/sda(centos6上是用partx来重读分区;centos7用partprobe)
[root@centos6 ~]# pvcreate /dev/sda6                                                              //创建物理卷
[root@centos6~]# vgcreate vgmysql /dev/sda6                                               //创建卷组
[root@centos6~]# lvcreate -l +100%FREE -n lvmysql vgmysql                         //创建逻辑卷
[root@centos6~]# mkfs.ext4 /dev/vgmysql/lvmysql                                           //格式化文件系统
[root@centos6 ~]# vim /etc/fstab 
 /dev/vgmysql/lvmysql    /app/dbdata             ext4    defaults        0 0         //将数据目录挂载到逻辑卷上
[root@centos6(nanyibo) ~]# mount –a                                             //开机自动挂载(读取/etc/fstab,挂载当前未挂载的文件系统,已挂载不会重新挂载,也不会更新挂载选项)
[root@centos6 ~]# chown mysql.mysql /app/dbdata                                  //改数据目录的权限
[root@centos6 ~]# chmod 700 /app/dbdata                             

(4)  解压二进制目录

[root@centos6 ~]# tar -xvf mariadb-10.2.14-linux-x86_64.tar.gz -C /usr/local/                             //-C解压到指定目录
[root@centos6 ~]# cd /usr/local/
[root@centos6  local]# ln -sv mariadb-10.2.14-linux-x86_64 mysql                                             //创建软链接
`mysql' -> `mariadb-10.2.14-linux-x86_64'

(5) 创建配置文件

[root@centos6  local]# cd /usr/local/mysql/
 [root@centos6  mysql]# mkdir /etc/mysql
 [root@centos6  mysql]# cp support-files/my-huge.cnf /etc/mysql/my.cnf
 [root@centos6  mysql]# vim /etc/mysql/my.cnf
 [mysqld]
……
datadir         = /app/dbdata
 innodb_file_per_table   = on
 skip_name_resolve = on
……

(6) 创建数据库文件

[root@centos6  mysql]# scripts/mysql_install_db --datadir=/app/dbdata --user=mysql

(7) 配置启动脚本

[root@centos6  mysql]# cp support-files/mysql.server /etc/init.d/mysqld
 [root@centos6  mysql]# chkconfig --add mysqld                                                       //将服务添加到chkconfig中
[root@centos6  mysql]# chkconfig mysqld on                                                                    //开机自启动
[root@centos6  mysql]# service mysqld restart   
 MariaDB server PID file could not be found!                [FAILED]
 Starting MariaDB.180710 18:00:14 mysqld_safe Logging to '/var/log/mysqld.log'.
 180710 18:00:14 mysqld_safe Starting mysqld daemon with databases from /app/dbdata
                                                            [  OK  ]

(8) 配置环境变量PATH

[root@centos6 ~]# vim /etc/profile.d/mage.sh
 export PATH=/usr/local/mysql/bin:$PATH
 [root@centos6 ~]# source /etc/profile.d/mage.sh

(9) 初始化mysql

[root@centos6 ~]# mysql_secure_installation 

四、mysql常用命令

create database name;                 创建数据库
use databasename;                       选择数据库
drop database name                      直接删除数据库,不提醒
show tables;                                   显示表
describe tablename;                      表的详细描述
select * from tablename;
Mysql命令查询一个表的记录总数(三种方法)
select count(*) from tablename;

MariaDB [student]> select count(*) from student;
 +----------+
 | count(*) |
 +----------+
 |        6 |
 +----------+
 1 row in set (0.17 sec)

或者
select count(*) as num from tablename;

MariaDB [student]> select count(*) as num from student;
 +-----+
 | num |
 +-----+
 |   6 |
 +-----+
 1 row in set (0.00 sec)

或者
select count(*) as total from tablename;
select 中加上distinct                                            去除重复字段
mysqladmin drop databasename                        删除数据库前,有提示。

select version(),current_date;                             显示当前mysql版本和当前日期

MariaDB [(none)]> select version();
 +---------------------+
 | version()           |
 +---------------------+
 | 10.2.14-MariaDB-log |
 +---------------------+
 1 row in set (0.00 sec)

select user();                                                             显示当前用户及主机名

MariaDB [(none)]> select user();
 +----------------+
 | user()         |
 +----------------+
 | root@localhost |
 +----------------+
 1 row in set (0.00 sec)

五、MySql中的SQL语句

1.显示所有的数据库:show databases;

MariaDB [(none)]> show databases;
 +---------------------+
 | Database            |
 +---------------------+
 | #mysql50#lost+found |
 | information_schema  |
 | magedb              |
 | mysql               |
 | performance_schema  |
 | student             |
 | test                |
 +---------------------+
 7 rows in set (0.19 sec)

(1)创建数据库 :create  database  student;

MariaDB [(none)]> create database student1;
 Query OK, 1 row affected (0.20 sec)

(2)删除数据库:drop database student1;

MariaDB [(none)]> drop database student1;
 Query OK, 0 rows affected (0.38 sec)

(3)选择数据库:use students;

MariaDB [(none)]> use student
 Database changed

2.建表:创建数据表的语法 : create table table_name (字段1 数据类型 , 字段2 数据类型);

mysql支持多种列类型:数值类型、日期/时间类型、字符串类型

注意:除了数值类型外,在使用的时候需要加引号

1.数据类型:

(1)整型

 tinyint(m) 1个字节 范围(-128~127) 

 smallint(m) 2个字节 范围(-32768~32767)

 mediumint(m)3个字节 范围(-8388608~8388607)

 int(m) 4个字节 范围(-2147483648~2147483647)

 bigint(m) 8个字节 范围(+-9.22*10的18次方)

取值范围如果加了unsigned,则最大值翻倍,如tinyint unsigned的取值范围为(0~255

(2)浮点型(float和double),近似值

  float(m,d) 单精度浮点型 8位精度(4字节) m总个数,d小数位

 double(m,d) 双精度浮点型 16位精度(8字节) m总个数,d小数位

 设一个字段定义为float(6,3),如果插入一个数123.45678,实际数据库里存的 是123.457,但总个数还以实际为准,即6位

(3)字符串(char,varchar,_text)

 char(n) 固定长度,最多255个字符

 varchar(n)可变长度,最多65535个字符

 tinytext 可变长度,最多255个字符

 text 可变长度,最多65535个字符

 mediumtext 可变长度,最多2的24次方-1个字符

 longtext 可变长度,最多2的32次方-1个字符

 BINARY(M) 固定长度,可存二进制或字符,允许长度为0-M字节,

 VARBINARY(M) 可变长度,可存二进制或字符,允许长度为0-M字节

 内建类型:ENUM枚举, SET集合

char和varchar:

1.char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉。所以char类型存储 的字符串末尾不能有空格,varchar不限于此。

 2.char(n) 固定长度,char(4)不管是存入几个字符,都将占用4个字节,varchar是存入的实际字 符数+1个字节(n< n>255),所以varchar(4),存入3个字符将占用4个字节。

 3.char类型的字符串检索速度要比varchar类型的快

varchar和text:

  1.varchar可指定n,text不能指定,内部存储varchar是存入的实际字符数+1个字节(n< n>255), text是实际字符数+2个字节。

  2.text类型不能有默认值

 3.varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速度快于text

 创建表

MariaDB [student]> create table student (id tinyint unsigned primary key, name varchar(20) not null, age tinyint unsigned,sex char(1) default "m" );
 Query OK, 0 rows affected (0.05 sec)

显示表的结构

MariaDB [student]> desc student;
 +-------+---------------------+------+-----+---------+-------+
 | Field | Type                | Null | Key | Default | Extra |
 +-------+---------------------+------+-----+---------+-------+
 | id    | tinyint(3) unsigned | NO   | PRI | NULL    |       |
 | name  | varchar(20)         | NO   |     | NULL    |       |
 | age   | tinyint(3) unsigned | YES  |     | NULL    |       |
 | sex   | char(1)             | YES  |     | m       |       |
 +-------+---------------------+------+-----+---------+-------+
 4 rows in set (0.02 sec)

查看所有的表

MariaDB [student]> show tables;
 +-------------------+
 | Tables_in_student |
 +-------------------+
 | lady              |
 | lesson            |
 | student           |
 +-------------------+
 3 rows in set (0.06 sec)

查看一个表的创建命令

MariaDB [student]> show create table student;
 +---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 | Table   | Create Table                                                                                                                                                                                                                                                     |
 +---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 | student | CREATE TABLE `student` (
   `id` tinyint(3) unsigned NOT NULL,
   `name` varchar(20) NOT NULL,
   `phone` char(11) DEFAULT NULL,
   `age` tinyint(3) unsigned DEFAULT NULL,
   `sex` char(1) DEFAULT 'm',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
 +---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 1 row in set (0.07 sec)

MariaDB [student]> 

查看一个表的状态

MariaDB [student]> show table status like 'student'\G;
 *************************** 1. row ***************************
            Name: student
          Engine: InnoDB
         Version: 10
      Row_format: Dynamic
            Rows: 6
  Avg_row_length: 2730
     Data_length: 16384
 Max_data_length: 0
    Index_length: 0
       Data_free: 0
  Auto_increment: NULL
     Create_time: 2018-09-18 08:40:57
     Update_time: 2018-09-18 09:07:27
      Check_time: NULL
       Collation: latin1_swedish_ci
        Checksum: NULL
  Create_options: 
         Comment: 
 1 row in set (0.13 sec)

ERROR: No query specified

MariaDB [student]> 

删除表

MariaDB [m33student]> drop table student1;
 Query OK, 0 rows affected (0.04 sec)

修改表

(1)修改表名

MariaDB [student]> alter table student rename s1;
 Query OK, 0 rows affected (0.79 sec)

(2)在表的指定位置添加列

MariaDB [m33student]> alter table student add phone char(11) after name;
 Query OK, 0 rows affected (0.05 sec)

  (3)修改表中某一列的数值类型并重新命名

MariaDB [student]> alter table s1 change column phone mobile char(11);
 Query OK, 0 rows affected (0.04 sec)
 Records: 0  Duplicates: 0  Warnings: 0

(4)删除某一列

MariaDB [student]> alter table emp drop column phone;
 Query OK, 0 rows affected (0.17 sec)
 Records: 0  Duplicates: 0  Warnings: 0

 (5)增加唯一性约束

MariaDB [student]> alter table s1 add unique key (mobile);
 Query OK, 0 rows affected (0.10 sec)
 Records: 0  Duplicates: 0  Warnings: 0

(6)创建索引

MariaDB [student]> alter table s1 add index(mobile);
 Query OK, 0 rows affected (0.05 sec)
 Records: 0  Duplicates: 0  Warnings: 0

MariaDB [student]> create index age_index on student(phone);

Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

(7)查看索引

MariaDB [student]> show indexes from s1\G;
 *************************** 1. row ***************************
         Table: s1
    Non_unique: 0
      Key_name: PRIMARY
  Seq_in_index: 1
   Column_name: id
     Collation: A
   Cardinality: 6
      Sub_part: NULL
        Packed: NULL
          Null: 
    Index_type: BTREE
       Comment: 
 Index_comment: 

(8)删除索引

MariaDB [student]> alter table s1 drop mobile;
 Query OK, 0 rows affected (0.06 sec)
 Records: 0  Duplicates: 0  Warnings: 0

3.添加数据  Insert into 表名 [(字段1 , 字段2 , ….)] values (值1 , 值2 , …..);
注意:如果向表中的每个字段都插入一个值,那么前面()括号内字段名可写也可不写

MariaDB [student]> insert into student values (1,'ms','18768896428',22,default);
 Query OK, 1 row affected (0.02 sec)

MariaDB [student]> insert into student (id,name) values (2,'zhanssan');
 Query OK, 1 row affected (0.02 sec)

一次性插入多行

MariaDB [student]> insert into student (id,name,sex) values (4,'liujin','f'),(5,'wangshuang','f'),(6,'masai',default);

Query OK,3 row affected (0.02 sec)

使用查询语句创建表 as可以省略

MariaDB [student]> create table emp as select * from student;

删除表中的所有行

MariaDB [student]> delete from lady;
 Query OK, 4 rows affected (0.01 sec)

通过查询结果来插入行

MariaDB [student]> insert into lady select * from student where sex='m';
 Query OK, 2 rows affected (0.02 sec)

4.update

MariaDB [student]> update student set phone='18438613802' where id=2;
 Query OK, 1 row affected (0.03 sec)
 Rows matched: 1  Changed: 1  Warnings: 0

所有学生的电话都被更新

MariaDB [student]> update emp set phone='18438613802' ;
 Query OK, 6 rows affected (0.02 sec)
 Rows matched: 6  Changed: 6  Warnings: 0

5.delete

MariaDB [student]> delete from emp where id=1;
 Query OK, 1 row affected (0.02 sec)

注意:删除的是表中的数据,表还存在。

MariaDB [student]> delete from emp;
 Query OK, 6 rows affected (0.03 sec)

MariaDB [student]> create table lesson (id tinyint unsigned, lesson varchar(20) not null default "linux" , score tinyint unsigned, primary key (id,lesson));

查看表中所有详细信息

MariaDB [student]> select * from s1;

选择指定列

MariaDB [student]> select id,score+10 score from lesson;

六、函数

单行函数:输入值的个数与输出值个数一样

1.字符串型

              upper

              lower

             concat (将列合并)

MariaDB [hellodb]> select concat (name,' age is ',age),gender from students;
 +------------------------------+--------+
 | concat (name,' age is ',age) | gender |
 +------------------------------+--------+
 | Hou Yi age is 22             | M      |
 | Ya Se age is 22              | M      |
 | An Qila age is 53            | F      |
 | Da Ji age is 32              | F      |
 | Sun Shangxiang age is 26     | F      |
 | Huang Zhong age is 46        | M      |
 | Liu Bei age is 19            | M      |

insert替换函数(列名,从第几位开始,替换几位,替换的内容)

MariaDB [hellodb]> select name,insert(phone,4,4,'****') phone from students;
 +----------------+-------------+
 | name           | phone       |
 +----------------+-------------+
 | Hou Yi         | 183****8170 |
 | Ya Se          | 183****8170 |
 | An Qila        | 157****8120 |
 | Da Ji          | 157****8120 |
 | Sun Shangxiang | 157****8120 |
 | Huang Zhong    | 183****8170 |

length(name)  长度

MariaDB [hellodb]> select name,length(name) 'name of length' from students;
+----------------+----------------+
| name           | name of length |
+----------------+----------------+
| Hou Yi         |              6 |
| Ya Se          |              5 |
| An Qila        |              7 |
| Da Ji          |              5 |

lpad(phone,13,'*'):向左填补,超过位数,则从右截断

MariaDB [hellodb]> select name,lpad(phone,13,'*') from students;
 +----------------+--------------------+
 | name           | lpad(phone,13,'*') |
 +----------------+--------------------+
 | Hou Yi         | **18338368170      |
 | Ya Se          | **18338368170      |
 | An Qila        | **15737618120      |
 | Da Ji          | **15737618120      |

rpad(phone,15,'*'):向右填补,超过位数,则从左截断

MariaDB [hellodb]> select name,rpad(phone,13,'*') from students;
 +----------------+--------------------+
 | name           | rpad(phone,13,'*') |
 +----------------+--------------------+
 | Hou Yi         | 18338368170**      |
 | Ya Se          | 18338368170**      |
 | An Qila        | 15737618120**      |
 | Da Ji          | 15737618120**      |
 | Sun Shangxiang | 15737618120**      |
 | Huang Zhong    | 18338368170**      |

replace(name,'Liu','Li')

MariaDB [hellodb]> select replace(name,'Liu','Li') from students;
 +--------------------------+
 | replace(name,'Liu','Li') |
 +--------------------------+
 | Hou Yi                   |
 | Ya Se                    |
 | An Qila                  |
 | Da Ji                    |
| Li Bei                   |

substr(phone,5,3) 从第5位开始取,往后一共取3位

MariaDB [hellodb]> select name,substr(phone,5,3) from students;
 +----------------+-------------------+
 | name           | substr(phone,5,3) |
 +----------------+-------------------+
 | Hou Yi         | 836               |
 | Ya Se          | 836               |
 | An Qila        | 761               |
 | Da Ji          | 761               |

2.数字型(可以不跟表)
         abs(-20); 取绝对值
         mod(10,3); 取模
         ceil(9.2);取不小于X的最小整数
         floor(3.6) 取不大于X的最大整数
         round 四舍五入
        round(3.41111,2)  得3.41
         truncate 截断

truncate(135.611111,-2); 得100

MariaDB [hellodb]> select truncate(135.611111,-2);
 +-------------------------+
 | truncate(135.611111,-2) |
 +-------------------------+
 | 100                     |
 +-------------------------+

3.日期型
     select now();  显示当前的时间
     select curdate();  显示当前的日期
     select curtime();  显示当前的时间
     select year(birthday); 显示指定日期的年
     select month(birthday); 显示指定日期的月
     select day(birthday); 显示指定日期是几号
     select dayname(now()); 显示指定日期是周几

MariaDB [hellodb]> select dayname(now()); 
 +----------------+
 | dayname(now()) |
 +----------------+
 | Thursday       |
 +----------------+
 1 row in set (0.02 sec)

字符转日期
 str_to_date('24-11-1700','%d-%m-%Y')  字符转日期

MariaDB [hellodb]> update students set birthday=str_to_date('24-11-1770','%d-%m-Y') where stuid=25;
 Query OK, 1 row affected (0.06 sec)
 Rows matched: 1  Changed: 1  Warnings: 0
25 | Sun Wukong     | 100 | 18338368170 | 1770-11-24 | M      |    NULL |      NULL |

日期转字符
 select date_format(birthday,'%Y年%m月%d日') 生日 from students;

| NULL              |
| 1770年11月24日    |

MariaDB [hellodb]> select date_format(birthday,'%Y年%m月%d日') 生日 from students;
 +-------------------+
 | 生日              |
 +-------------------+
 | NULL              |
 | NULL              |

null函数
     ifnull(score,0)
     coalesce(score,0)
case else

select courseid,case courseid
     -> when 2 then score+10
     -> when 3 then score+0
     -> when 4 then score+20
     -> else score
     -> end
     -> as score
     -> from scores;

多行函数(聚合函数、组函数)

count() 返回表中满足where条件的行的数量,如没有Where条件,列出所有行的总数 

 MariaDB [hellodb]> Select count(*) from scores where score > 50;
     +----------+
     | count(*) |
     +----------+
     |       14 |
     +----------+
     MariaDB [hellodb]> select count(distinct classid) from students;
     +-------------------------+
     | count(distinct classid) |
     +-------------------------+
     |                       7 |
     +-------------------------+
     1 row in set (0.00 sec)

max()  min()  avg()  sum()

select max(score) from scores;

 select courseid,sum(score) scoreall from scores group by courseid;

算平均值时,注意null不会参与组函数,所以要先用ifnull将null转为0,如下

     MariaDB [hellodb]> select avg(ifnull(score,0)) from scores;
     +----------------------+
     | avg(ifnull(score,0)) |
     +----------------------+
     |              73.0588 |
     +----------------------+
     1 row in set (0.00 sec)

coalesce(score,0)如果非空则显示score,如果为空则为0

MariaDB [hellodb]> select stuid,coalesce(score,0) score from scores;
 +-------+-------+
 | stuid | score |
 +-------+-------+
 |     1 | 77    |
 |     1 | 93    |
 |     2 | 47    |
 |     2 | 97    |
 |     9 | 88    |
 |    25 | 0     |
 +-------+-------+

 MariaDB [hellodb]> select courseid,avg(score) from scores group by courseid;

MariaDB [hellodb]> select courseid,avg(score) from scores group by courseid;
 +----------+------------+
 | courseid | avg(score) |
+----------+------------+
 |        1 | 73.6667    |
 |        2 | 75.2500    |
 |        3 | 93.0000    |
 |        4 | 57.0000    |
 |        5 | 85.3333    |
 |        6 | 84.0000    |
 |        7 | 73.0000    |
 +----------+------------+
 7 rows in set (0.00 sec)

select courseid,avg(nullif(score,0)) as avg from scores group by courseid having avg>60; 对的

where发生在group by 之前,所以不能对group by 后的结果进行筛选,而要用having

MariaDB [hellodb]> select courseid,avg(ifnull(score,0)) avg from scores group by courseid having avg>60;

select * from students limit 6  取前6行,即1-6行
select * from students limit 6,3 取6行后的3行,即7,8,9行
练习:导入hellodb.sql生成数据库

(1)在students表中,查询年龄大于25岁,且为男性的同学的名字和年龄
MariaDB [hellodb]> select Name,age from students where age>25 and gender='m';
(2)以ClassID为分组依据,显示每组的平均年龄
MariaDB [hellodb]> select classid ,avg(age) age from students group by classid having classid is not null;
(3)显示第2题中平均年龄大于30的分组及平均年龄
MariaDB [hellodb]> select classid ,avg(age) age from students group by classid having age>30 and classid is not null;
(4)显示以L开头的名字的同学的信息
MariaDB [hellodb]> select * from students where name like 'L%';
(5)显示TeacherID非空的同学的相关信息
MariaDB [hellodb]> select * from students where TeacherID is NOT NULL;
(6)以年龄排序后,显示年龄最大的前10位同学的信息
MariaDB [hellodb]> select * from students order by age desc limit 10;
(7)查询年龄大于等于20岁,小于等于25岁的同学的信息
mysql> select * from students where age >= 20 and age <=25;
mysql> select * from students where age between 20 and 25;

七、多表连接
 1. 内连接 inner join

 select s.name student_name,c.class class from students s inner join classes c on s.classid=c.classid;

     内连接 交集:仅查看有老师的学员和有学员的老师的信息

MariaDB [hellodb]> select s.name student_name,t.name teacher_name from students s inner join teachers t on s.teacherid=t.tid;

 2.自然连接 natural join 基于同名列

select s.name student_name,c.class class from students s natural join classes c ;

3.非等值连接

select s.name student_name,s.salary salary,sa.grade from students s,salgrade sa where s.salary between sa.losal and sa.hisal;

4.using

select s.name student_name,c.class class from students s join classes c using (classid);

5.自连接 

select s.name student_name,a.name admin_name from students s join students a on s.classadminid=a.stuid;

6.外连接

    (1)左外连接

  select s.name student_name,t.name teacher_name from students s left join teachers t on s.teacherid=t.tid;

       左外连接 显示所有学员信息,包含有老师的学员和没老师的学员

MariaDB [hellodb]> select s.name student_name,t.name teacher_name from students s left join teachers t on s.teacherid=t.tid;

        左外连接 仅显示没老师的学员

MariaDB [hellodb]> select s.name student_name,t.name teacher_name from students s left join teachers t on s.teacherid=t.tid where t.name is null;

     (2)右外连接

select s.name student_name,t.name teacher_name from students s right join teachers t on s.teacherid=t.tid;

          右外连接 显示所有的老师信息,包含有学员的老师,和没学员的老师

MariaDB [hellodb]> select s.name student_name,t.name teacher_name from students s right join teachers t on s.teacherid=t.tid;

         右外连接 仅显示没学员的老师

MariaDB [hellodb]> select s.name student_name,t.name teacher_name from students s right join teachers t on s.teacherid=t.tid where s.name is null;

7.三表连接

    取出学生名和所学的课程名 

select s.name as student_name, co.course as course from students s join coc c on s.classid=c.classid join courses co on c.courseid=co.courseid;

8.并集 

(1)显示所有老师和学员

select s.name student_name,t.name teacher_name from students s left join teachers t on s.teacherid=t.tid
     -> union
     -> select s.name student_name,t.name teacher_name from students s right join teachers t on s.teacherid=t.tid;

(2)仅显示没老师的学员和没学员的老师

MariaDB [hellodb]> select * from (select s.name student_name,t.name teacher_name from students s left join teachers t on s.teacherid=t.tid union select s.name student_name,t.name teacher_name from students s right join teachers t on s.teacherid=t.tid) as a where student_name is null or teacher_name is null;

9.迪卡尔乘积  交叉连接

MariaDB [hellodb]> select s.name student_name,t.name teacher_name from students s cross join teachers t ;

10.子查询

在子查询中,如果子查询得出多个值,那么要在括号外写上any(some),all,in。
> any  大于最小值
> all  大于最大值
< any  小于最大值
< all  小于最小值

练习:把后羿的年龄改为与凯同岁。

update students st set age=(select age from (select * from students) a where name='Kai')  where name='hou yi';

作业:
导入hellodb.sql,以下操作在students表上执行
1、以ClassID分组,显示每班的同学的人数
MariaDB [hellodb]> select classid,count(stuid) student_count from students group by classid having classid is not null;

2、以Gender分组,显示其年龄之和
MariaDB [hellodb]> select gender,sum(age) from students group by gender;

3、以ClassID分组,显示其平均年龄大于25的班级
MariaDB [hellodb]> select classid,avg(age) age from students group by classid having avg(age) > 25 and classid is not null;

4、以Gender分组,显示各组中年龄大于25的学员的年龄之和
MariaDB [hellodb]> select gender,sum(age) sum_age from students where age > 25 group by gender;

5、显示前5位同学的姓名、课程及成绩
MariaDB [hellodb]> select s.name ,c.course,sc.score from (select * from students limit 5) as s left join scores sc on sc.stuid=s.stuid left  join courses c on sc.courseid=c.courseid;

6、显示其成绩高于80的同学的名称及课程;
mysql> select s.name student_name,sc.score,c.course course from students s join scores sc on s.stuid=sc.stuid join courses c on sc.courseid=c.courseid where sc.score>80;
7、求前8位同学每位同学自己两门课的平均成绩,并按降序排列
MariaDB [hellodb]> select s.name,avg(sc.score) avg_score from (select * from students limit 8) s join scores sc on s.stuid=sc.stuid  group by s.stuid order by avg_score desc;
8、显示每门课程课程名称及学习了这门课的同学的个数
MariaDB [hellodb]> select c.course course,count(s.stuid) count from students s join coc co on s.classid=co.classid join courses c on co.courseid=c.courseid group by c.course;

9、显示其年龄大于平均年龄的同学的名字
MariaDB [hellodb]> select name,age from students where age > (select avg(age) from students);

10、显示其学习的课程为第1、2,4或第7门课的同学的名字
MariaDB [hellodb]> select s.name,c.courseid from students s join coc c on s.classid=c.classid where c.courseid in (1,2,4,7);

11、显示其成员数最少为3个的班级的同学中年龄大于同班同学平均年龄的同学
MariaDB [hellodb]> select s.name student_name,age from students s join (select classid from students group by classid having classid is not null and count(stuid) > 3) as c on s.classid=c.classid group by s.classid having age > avg(s.age);

12、统计各班级中年龄大于全校同学平均年龄的同学
MariaDB [hellodb]> select classid,name as student_name,age from students where age > (select avg(age) from students) and classid is not null order by classid;

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/f-h-j-11-7/p/9690880.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值