六:MySQL之SQL语句

Posted captain-jiang

tags:

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

一.DDL:数据定义语言

(操作物理文件目录本身)

1. 增create

#库

 #创建库
    create database dbname;    database schema一样,都是建库的意思
    create schema dbname;
    #?增加判断,如果已经存在库,会避免程序报错
    create database if not exists dbname; 
    #创建库并设置字符集,default可以不写
    create database db1 default charset utf8;
    查看如何创建的数据库db1
    mysql> show create database db1 ;
    +----------+--------------------------------------------------------------+
    | Database | Create Database                                              |
    +----------+--------------------------------------------------------------+
    | db1      | CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8 */ |
    +----------+--------------------------------------------------------------+
    1 row in set (0.00 sec)
    #校验规则,建库时可以指定,源码安装时也可以指定
    create database db3 charset utf8 collate utf8_bin;
mysql> show create database db3;
+----------+-------------------------------------------------------------------------------+
| Database | Create Database                                                               |
+----------+-------------------------------------------------------------------------------+
| db3      | CREATE DATABASE `db3` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */ |
+----------+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)

#表

#建表
create table student2(
sid int primary key auto_increment,
sname varchar(20) not null,
sage tinyint unsigned not null,
sgender enum('f','m','haoge') default 'm',
cometime datetime default now());
#插入数据
#默认可以不写的参数,需要在表下面添加相对应的别名:student4(sname,sage,sgender)
mysql> insert into s into student4(sname,sage,sgender) values('jiangwei',29,'m');
Query OK, 1 row affected (0.01 sec)
#查看表数据
mysql> select * from student4
    -> ;
+-----+----------+------+---------+---------------------+
| sid | sname    | sage | sgender | cometime            |
+-----+----------+------+---------+---------------------+
|   1 | jiangwei |   29 | m       | 2019-12-18 17:00:01 |
+-----+----------+------+---------+---------------------+
1 row in set (0.00 sec)
#如果要求sid从001开始002---003等需要用一个参数?:zerofill
如下:?
create table student4(
sid int(3) zerofill primary key auto_increment,
sname varchar(20) not null,
sage tinyint unsigned not null,
sgender enum('f','m','haoge') default 'm',
cometime datetime default now());

## 规范的建表语句

create table student7(
sid int zerofill primary key auto_increment comment '学号',
sname varchar(20) not null comment '学生姓名',
#not null 必须要填写,不能为空
sage tinyint unsigned not null comment '学生年龄',
#非负并且不能为空,注意unsigned是要约束tinyint的,所以跟在tinyint后面
#加了无符号,数值变成128+128,前面的负的变成正的
sgender enum('f','m') default 'm' comment '学生性别',
#default 默认值为m
cometime datetime default now() comment '入学时间') engine=innodb charset utf8;
#插入数据
mysql> insert into student7 values(1,'jerry',18,'m',now());
Query OK, 1 row affected (0.00 sec)

mysql> select * from student7;
+------------+-------+------+---------+---------------------+
| sid        | sname | sage | sgender | cometime            |
+------------+-------+------+---------+---------------------+
| 0000000001 | jerry |   18 | m       | 2019-12-18 17:27:09 |
+------------+-------+------+---------+---------------------+
1 row in set (0.00 sec)

#comment的注释的目的可以清晰知道代表的意思,是能通过show create table student7;查看
mysql> show create table student7;
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                 |
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| student7 | CREATE TABLE `student7` (
  `sid` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT '学号',
  `sname` varchar(20) NOT NULL COMMENT '学生姓名',
  `sage` tinyint(3) unsigned NOT NULL COMMENT '学生年龄',
  `sgender` enum('f','m') DEFAULT 'm' COMMENT '学生性别',
  `cometime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '入学时间',
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8                   |
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

2. 删drop

drop     #库     drop database xxx;     
         #表     drop table test.student; 

3. 改alter

    alter(针对库的改很少)
    #库(修改数据库字符集)
    alter database zls10 charset utf8;
    #表
    mysql> create table stu1(haoge varchar(10));
    mysql> desc stu1;
    +-------+-------------+------+-----+---------+-------+
    | Field | Type       | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | haoge | varchar(10) | YES |     | NULL   |       |
    +-------+-------------+------+-----+---------+-------+
?
-- 添加字段
mysql> alter table stu1 add qls char(10);
-- 在指定字段之前插入字段
mysql> alter table stu1 add dawei int first;
-- 将字段插入到两个字段的中间
mysql> alter table stu1 add feishang varchar(10) after dawei;
-- 删除字段
mysql> alter table stu1 drop haoge;
-- 修改字段的数据类型
mysql> alter table stu1 modify feishang int;
-- 修改字段的名字和数据类型
mysql> alter table stu1 change feishang haoge char(10);
-- 修改字段的约束
mysql> alter table stu1 modify dawei int not null;
-- 修改表名
mysql> alter table stu1 rename stu;
-- 修改id字段为主键字段,且自增
mysql> alter table student1 modify id int primary key auto_increment;

二 .DML:数据操作语言

(操作文件中的内容)

1.增insert

注意:不管在查字段还是加字段,建议先desc查下表结构

mysql> desc student7;
+----------+---------------------------+------+-----+-------------------+
| Field   | Type                     | Null | Key | Default           |
+----------+---------------------------+------+-----+-------------------+
| sid     | int(10) unsigned zerofill | NO   | PRI | NULL             |
| sname   | varchar(20)               | NO   |     | NULL             |
| sage     | tinyint(3) unsigned       | NO   |     | NULL             |
| sgender | enum('f','m','haoge')     | YES |     | m                 |
| cometime | datetime                 | YES |     | CURRENT_TIMESTAMP |
+----------+---------------------------+------+-----+-------------------+
?
1.不规范写法
mysql> insert into student7 values(1,'suibian',18,'f',now());
?
2.规范写法
mysql> insert into student7(sname,sage,sgender) values('zls',18,'m');
#插入多行
mysql> insert into student7(sname,sage,sgender) values('qls',20,'f'),('dawei',17,'m');
或
insert into student7(sname,sage,sgender)
values('qls',20,'f'),
('dawei',17,'m');

2. 改(update)

update(危险)
#没有进入任何库,需要加绝对路径test.student7
#这种比较危险,因为没有加条件,所以会全表都生效
mysql> update test.student7 set sgender='f';

1.规范,必须加where条件
mysql> update test.student7 set sgender='m' where sname='zls';

2.就算需求是整列数据都需要修改,也必须加where
mysql> update test.student7 set sage=30 where 1=1;

3.加多条件
mysql> update test.student7 set sname='qls' where sage=31 and sgender='f';

3. 删(delete)

delete(危险)
#删除test下的student7表,到一定要加条件
mysql> delete from test.student7;

1.规范,必须加where条件
mysql> delete from test.student7 where sname='zls';

2.就算需求是整列数据都需要删除,也必须加where
mysql> delete from test.student7 where 1=1;

补充:delete和truncate的区别

#查询表
mysql> select * from student7;
+------------+-------+------+---------+---------------------+
| sid        | sname | sage | sgender | cometime            |
+------------+-------+------+---------+---------------------+
| 0000000001 | jerry |   18 | m       | 2019-12-18 17:27:09 |
| 0000000002 | jiang |   19 | m       | 2019-12-19 10:55:39 |
| 0000000003 | zhang |   20 | f       | 2019-12-19 10:55:39 |
| 0000000004 | wang  |   40 | m       | 2019-12-19 16:55:17 |
+------------+-------+------+---------+---------------------+
4 rows in set (0.00 sec)

#用delete删除student7表
mysql> delete from student7 where 1=1;
Query OK, 4 rows affected (0.00 sec)

mysql> select * from student7;
Empty set (0.00 sec)

#此时再插入两行数据
mysql> insert into student7(sname,sage,sgender) 
    -> values('jerry01',20,'f'),
    -> ('jerry02',30,'m');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

#我们会发现sid从5开始,什么原因呢?
mysql> select * from student7;
+------------+---------+------+---------+---------------------+
| sid        | sname   | sage | sgender | cometime            |
+------------+---------+------+---------+---------------------+
| 0000000005 | jerry01 |   20 | f       | 2019-12-19 17:00:30 |
| 0000000006 | jerry02 |   30 | m       | 2019-12-19 17:00:30 |
+------------+---------+------+---------+---------------------+
2 rows in set (0.00 sec)

#使用truncate删除表
mysql> truncate student7;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from student7;
Empty set (0.00 sec)

#再次插入数据
mysql> insert into student7(sname,sage,sgender) 
    -> values('jerry03',40,'m'),
    -> ('jerry04',50,'f');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

#查看表数据,从1开始。
mysql> select * from student7;
+------------+---------+------+---------+---------------------+
| sid        | sname   | sage | sgender | cometime            |
+------------+---------+------+---------+---------------------+
| 0000000001 | jerry03 |   40 | m       | 2019-12-19 17:03:19 |
| 0000000002 | jerry04 |   50 | f       | 2019-12-19 17:03:19 |
+------------+---------+------+---------+---------------------+
2 rows in set (0.00 sec)

问题:为什么truncate删除后写数据从头开始,delete删除后从之前的开始?
mysql> show create table student7;
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                 |
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| student7 | CREATE TABLE `student7` (
  `sid` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT '学号',
  `sname` varchar(20) NOT NULL COMMENT '学生姓名',
  `sage` tinyint(3) unsigned NOT NULL COMMENT '学生年龄',
  `sgender` enum('f','m') DEFAULT 'm' COMMENT '学生性别',
  `cometime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '入学时间',
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

# 可以看到这边有个自增AUTO_INCREMENT=3,truncate就没有               |

+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> truncate student7;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from student7;
Empty set (0.00 sec)

mysql> show create table student7;
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| student7 | CREATE TABLE `student7` (
  `sid` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT '学号',
  `sname` varchar(20) NOT NULL COMMENT '学生姓名',
  `sage` tinyint(3) unsigned NOT NULL COMMENT '学生年龄',
  `sgender` enum('f','m') DEFAULT 'm' COMMENT '学生性别',
  `cometime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '入学时间',
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8                   |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

4. 使用update代替delete做伪删除

为什么要做伪删除?

目的:伪删除一般是为了数据恢复,这样需要的时候,还可以还原数据。一般对于数据量不大的数据库,如果不是为了空间考虑,就不需要去真实的删除数据,而是通过一个标记来处理。

如何实现?

我们可以给生产的表创建一个状态列,此状态列只有0和1,0代表删除,1代表未删除,0代表的删除就是伪删除,呈现给客户的显示已经删除,但是在数据库中只是由状态1 变成0,实际数据依然存在,当某VIP客户要求恢复数据,我们只需要在数据库将状态0设置成1,就可以实现秒级恢复,这就是伪删除。

那么伪删除的数据会永久存在吗?个人认为,可以设置时间,比如1个月三个月,内存大的服务器可以更久。

具体操作:

#1.先要给生产的表,创建一个状态列
mysql> alter table student7 add state enum('0','1') default '1';
mysql> desc student7;
+----------+---------------------------+------+-----+-------------------+----------------+
| Field    | Type                      | Null | Key | Default           | Extra          |
+----------+---------------------------+------+-----+-------------------+----------------+
| sid      | int(10) unsigned zerofill | NO   | PRI | NULL              | auto_increment |
| sname    | varchar(20)               | NO   |     | NULL              |                |
| sage     | tinyint(3) unsigned       | NO   |     | NULL              |                |
| sgender  | enum('f','m')             | YES  |     | m                 |                |
| cometime | datetime                  | YES  |     | CURRENT_TIMESTAMP |                |
| state    | enum('0','1')             | YES  |     | 1                 |                |
+----------+---------------------------+------+-----+-------------------+----------------+
6 rows in set (0.00 sec)

#2.插入数据
mysql> insert into student7(sname,sage,sgender) values('qls',20,'f'), ('dawei',17,'m'),('zls',18,'m');
mysql> insert into student7(sname,sage,sgender) values('qls',20,'f'), ('dawei',17,'m'),('zls',18,'m');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> 
mysql> select * from student7;
+------------+-------+------+---------+---------------------+-------+
| sid        | sname | sage | sgender | cometime            | state |
+------------+-------+------+---------+---------------------+-------+
| 0000000001 | qls   |   20 | f       | 2019-12-19 20:09:50 | 1     |
| 0000000002 | dawei |   17 | m       | 2019-12-19 20:09:50 | 1     |
| 0000000003 | zls   |   18 | m       | 2019-12-19 20:09:50 | 1     |
+------------+-------+------+---------+---------------------+-------+

#3.删除数据
mysql> update student7 set state='0' where sid=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from student7;
+------------+-------+------+---------+---------------------+-------+
| sid        | sname | sage | sgender | cometime            | state |
+------------+-------+------+---------+---------------------+-------+
| 0000000001 | qls   |   20 | f       | 2019-12-19 20:09:50 | 1     |
| 0000000002 | dawei |   17 | m       | 2019-12-19 20:09:50 | 1     |
| 0000000003 | zls   |   18 | m       | 2019-12-19 20:09:50 | 0     |
+------------+-------+------+---------+---------------------+-------+
3 rows in set (0.00 sec)

#4.查询数据
?mysql> select * from student7 where state='1';
+------------+-------+------+---------+---------------------+-------+
| sid        | sname | sage | sgender | cometime            | state |
+------------+-------+------+---------+---------------------+-------+
| 0000000001 | qls   |   20 | f       | 2019-12-19 20:09:50 | 1     |
| 0000000002 | dawei |   17 | m       | 2019-12-19 20:09:50 | 1     |
+------------+-------+------+---------+---------------------+-------+
2 rows in set (0.00 sec)

#注意:需要和开发统一update替代delete,状态0和1,简单来说用:户删除---开发程序得到消息---状态要变成0----消息下达到数据库----数据库得到消息程序里就会执行 update from xxx.xxx where id=1;然后查询的时候 ,select * from xxx.xxx where state=1;
别吐槽,我都说了,简单来说。
最终客户查询时看到的是已删除的界面,但数据依然在服务器中。

三.DCL:数据控制语言

#grant
grant all on *.* to root@'%' identified by '123' with grant option;

#其他参数(扩展)
max_queries_per_hour:一个用户每小时可发出的查询数量
max_updates_per_hour:一个用户每小时可发出的更新数量
max_connections_per_hour:一个用户每小时可连接到服务器的次数
max_user_connections:允许同时连接数量
?
grant select on test.* to dev@'%' identified by '123' with grant option max_user_connections 1;
?
grant select,update on test.* to dev5@'%' identified by '123' with
grant option
max_user_connections 2
max_queries_per_hour 4
max_updates_per_hour 2
max_connections_per_hour 3;
?
#revoke回收权限
mysql> revoke select on test.* from dev5@'%';

四.DQL:数据查询语言

1. 基础用法:

1.1 导入一张城市表

mysql> source /root/world.sql
mysql> show tables from world;
+-----------------+
| Tables_in_world |
+-----------------+
| city           | #城市表
| country         | #国家表
| countrylanguage | #国家语言表

1.2 查询所有数据

mysql> select * from world.city; 

1.3 指定列查询

mysql> select id,name from world.city; 

1.4 limit分页

(京东一页60个商品,数据库就是这样的方式排序的)

mysql> select * from city limit 10;
+----+----------------+-------------+---------------+------------+
| ID | Name           | CountryCode | District     | Population |
+----+----------------+-------------+---------------+------------+
|  1 | Kabul         | AFG         | Kabol         |    1780000 |
|  2 | Qandahar       | AFG         | Qandahar     |     237500 |
|  3 | Herat         | AFG         | Herat         |     186800 |
|  4 | Mazar-e-Sharif | AFG         | Balkh         |     127800 |
|  5 | Amsterdam     | NLD         | Noord-Holland |     731200 |
|  6 | Rotterdam     | NLD         | Zuid-Holland |     593321 |
|  7 | Haag           | NLD         | Zuid-Holland |     440900 |
|  8 | Utrecht       | NLD         | Utrecht       |     234323 |
|  9 | Eindhoven     | NLD         | Noord-Brabant |     201843 |
| 10 | Tilburg       | NLD         | Noord-Brabant |     193238 |
+----+----------------+-------------+---------------+------------+
?
mysql> select * from world.city where countrycode='CHN' limit 0,60;     #第一页
mysql> select * from world.city where countrycode='CHN' limit 60,60; #第二页
mysql> select * from world.city where countrycode='CHN' limit 120,60; #第三页

1.5 排序 order by

mysql> select * from world.city where countrycode='CHN' order by population desc limit 0,60;
#以京东为例?
select * from 京东 where 商品名称='gucci' order by 价格 limit 0,60;?
#as设置别名
mysql> select id as 商品序号,name as 商品名称,countrycode as 商品别名,district as 商品厂商,population as 商品价格 from world.city wherre countrycode='CHN' order by population desc limit 0,10;
+--------------+--------------------+--------------+--------------+--------------+
| 商品序号     | 商品名称           | 商品别名     | 商品厂商     | 商品价格     |
+--------------+--------------------+--------------+--------------+--------------+
|         4080 | zls               | CHN         | zls         |      9999999 |
|         1890 | Shanghai           | CHN         | Shanghai     |      9696300 |
|         1891 | Peking             | CHN         | Peking       |      7472000 |
|         1892 | Chongqing         | CHN         | Chongqing   |      6351600 |
|         1893 | Tianjin           | CHN         | Tianjin     |      5286800 |
|         1894 | Wuhan             | CHN         | Hubei       |      4344600 |
|         1895 | Harbin             | CHN         | Heilongjiang |      4289800 |
|         1896 | Shenyang           | CHN         | Liaoning     |      4265200 |
|         1897 | Kanton [Guangzhou] | CHN         | Guangdong   |      4256300 |
|         1898 | Chengdu           | CHN         | Sichuan     |      3361500 |
+--------------+--------------------+--------------+--------------+--------------+

1.6 分组 group by

#计算类的函数:

count:统计

sum:求和

avg:平均值

min:最小值

max:最大值

distinct:去重

#此时此刻,我想吟诗一首

1.遇到统计想函数

2.形容词前groupby

3.函数中央是名词

4.列名select后添加

#统计世界上每个国家的总人口数

1.sum()
2.group by countrycode
3.sum(population)
??
select countrycode,sum(population) from world.city group by countrycode;
+-------------+-----------------+
| CountryCode | sum(Population) |
+-------------+-----------------+
| ABW         |           29034 |
| AFG         |         2332100 |
| AGO         |         2561600 |
| AIA         |            1556 |
| ALB         |          270000 |
| AND         |           21189 |
| ANT         |            2345 |
| ARE         |         1728336 |
| ARG         |        19996563 |
| ARM         |         1633100 |
| ASM         |            7523 |
| ATG         |           24000 |
| AUS         |        11313666 |
...省略

#统计中国各个省的人口数量

sum()
group by district
sum(population)
?
mysql> select countrycode,district,sum(population) from world.city where countrycode='chn' group by district;
+----------------+-----------------+
| District       | sum(Population) |
+----------------+-----------------+
| Anhui          |         5141136 |
| Chongqing      |         6351600 |
| Fujian         |         3575650 |
| Gansu          |         2462631 |
| Guangdong      |         9510263 |
| Guangxi        |         2925142 |
| Guizhou        |         2512087 |
| Hainan         |          557120 |
| Hebei          |         6458553 |
| Heilongjiang   |        11628057 |
| Henan          |         6899010 |
| Hubei          |         8547585 |
....省略

1.7 模糊查询(like)

#模糊查询,只要带H就能查询
mysql> select * from city where countrycode like '%H%';

#以H开头
mysql> select * from city where countrycode like 'h%';

#以H结尾
mysql> select * from city where countrycode like '%h';

1.8 多条件查询

#多条件查询(一般来说,and接两个不相同的字段)
mysql> select * from city where countrycode='chn' and population > 100000;

mysql> select * from city where countrycode='chn' or countrycode='usa';

mysql> select * from city where countrycode in ('chn','usa');   

1.9 联合查询

mysql> explain select * from city where countrycode='chn' union all select * from city where countrycode='usa'; 

1.10 范围查询 > < >= <= <>

mysql> select * from city where population < 100;

mysql> select * from city where population != 100;

mysql> select * from city where population <> 100;

mysql> select * from city where population>100 and population<200;

2. 高级用法:

联表查询:

关系型数据库,免不了表之间存在各种引用与关联。这些关联是通过主键与外键搭配来形成的。 所以,取数据时,很大情况下单张表无法满足需求,额外的数据则需要将其他表加入到查询中来, 这便是联表查询的操作。

主键和外键:

1:主键和外键的定义
主键(primary key):一列(或一组列),其值能够唯一区分表中每个行 。
外键(foreign key) 外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系 
借用其他博客中的三个数据表解析一下:
学生表(学号,姓名,性别,班级)  //  学号唯一,能确定学生表的一行
课程表(课程编号,课程名,学分)   //  课程编号唯一,能确定课程表的一行
成绩表(学号,课程号,成绩)     //   学号和课程号才能唯一确定哪个人哪门课得了多少分,学号和课程号这两列为主键
2:是哪个表的外键?
以上面的成绩表为例,学号和课程号是成绩表的主键,那么学号是成绩表的外键还是学生表的外键?当然是成绩表的外键,
因为学号是学生表的主键呀,怎么可能是外键?同理成绩表课程号也应该是成绩表的外键。其实,外键主要建立与其他表的联系,
如果我们想知道成绩表中某一行成绩是谁考的,啥性别,在哪个班级,就可通过成绩表的外键学号与学生表建立一种关系。

1.1 联表查询---传统连接

# 世界上人口数量小于100的城市在哪个国家,人口数是多少?
国家名             城市名             人口数量
country.name      city.name         city.population

select country.name as 国家名,city.name as 城市名,city.population as 城市人口数量
from city,country
where city.countrycode=country.code
and city.population < 100;

+-----------+-----------+--------------------+
| 国家名    | 城市名    | 城市人口数量       |
+-----------+-----------+--------------------+
| Pitcairn  | Adamstown |                 42 |
+-----------+-----------+--------------------+


#世界上人口数量小于100的城市在哪个国家,人口数量是多少,说的什么语言?
国家名             城市名            城市人口数量               语言
country.name       city.name        city.population       countrylanguage.language


select country.name,city.name,city.population,countrylanguage.language
from city,country,countrylanguage
where city.countrycode=country.code
and country.code=countrylanguage.countrycode
and city.population<100;

+----------+-----------+------------+-------------+
| name     | name      | population | language    |
+----------+-----------+------------+-------------+
| Pitcairn | Adamstown |         42 | Pitcairnese |
+----------+-----------+------------+-------------+

1.2 联表查询----内连接(企业中常用)

### inner join on (inner可以忽略)

# 世界上 人口数量小于100的城市,在哪个国家,人口数量是多少?
国家名             城市名                 城市人口数量
country.name      city.name             city.population

select country.name,city.name,city.population
from city join country
on city.countrycode=country.code
where city.population<100;

+----------+-----------+------------+
| name     | name      | population |
+----------+-----------+------------+
| Pitcairn | Adamstown |         42 |
+----------+-----------+------------+

#世界上人口数量小于100的城市在哪个国家,人口数量是多少,说的什么语言?
国家名             城市名            城市人口数量               语言
country.name       city.name        city.population       countrylanguage.language


# A join B on 1 join C on 2 join D on 3

select country.name,city.name,city.population,countrylanguage.language
from countrylanguage join city
on countrylanguage.countrycode=city.countrycode
join country
on city.countrycode=country.code
where city.population<100;

+----------+-----------+------------+-------------+
| name     | name      | population | language    |
+----------+-----------+------------+-------------+
| Pitcairn | Adamstown |         42 | Pitcairnese |
+----------+-----------+------------+-------------+

注意:一般来说,我们需要,小表在前,大表在后

1.3 联表查询----自连接

### natural join

大前提条件:两个表的等价条件,必须有相同的字段名

## 人口数量小于100的城市,国家代码是什么,说的什么语言,人口数量是多少?
国家代码            城市名           语言                       城市人口数量
city.countrycode   city.name       countrylanguage.language  city.population

select city.countrycode,city.name,countrylanguage.language,city.population
from countrylanguage natural join city
where city.population<100;
#countrylanguage表和city表里都有countrycode字段,所以可以使用natural join

mysql> select city.countrycode,city.name,countrylanguage.language,city.population
    -> from countrylanguage natural join city
    -> where city.population<100;
+-------------+-----------+-------------+------------+
| countrycode | name      | language    | population |
+-------------+-----------+-------------+------------+
| PCN         | Adamstown | Pitcairnese |         42 |
+-------------+-----------+-------------+------------+

1.4 联表查询----左外连接

left join 是left outer join的简写,它的全称是左外连接,是外连接中的一种。(只显示左边的 表)

如下图:左(外)连接,左表(a_table)的记录将会全部表示出来,而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL。

技术图片

mysql> select city.name,country.code,country.name
    -> from city left join country 
    -> on city.countrycode=country.code 
    -> and city.population<100 limit 10;
+----------------+-------------+------+
| name           | countrycode | name |
+----------------+----  ---------+------+
| Kabul          | AFG         | NULL |
| Qandahar       | AFG         | NULL |
| Herat          | AFG         | NULL |
| Mazar-e-Sharif | AFG         | NULL |
| Amsterdam      | NLD         | NULL |
| Rotterdam      | NLD         | NULL |
| Haag           | NLD         | NULL |
| Utrecht        | NLD         | NULL |
| Eindhoven      | NLD         | NULL |
| Tilburg        | NLD         | NULL |
+----------------+-------------+------+

1.5 联表查询----右外连接

right join是right outer join的简写,它的全称是右外连接,是外连接中的一种。(只显示右边的 表)

如下图:与左(外)连接相反,右(外)连接,左表(a_table)只会显示符合搜索条件的记录,而右表(b_table)的记录将会全部表示出来。左表记录不足的地方均为NULL。

技术图片

mysql> select city.name,city.countrycode,country.name
    -> from city right join country 
    -> on city.countrycode=country.code
    -> and city.population<100 limit 10;
+------+-------------+----------------------+
| name | countrycode | name                 |
+------+-------------+----------------------+
| NULL | NULL        | Aruba                |
| NULL | NULL        | Afghanistan          |
| NULL | NULL        | Angola               |
| NULL | NULL        | Anguilla             |
| NULL | NULL        | Albania              |
| NULL | NULL        | Andorra              |
| NULL | NULL        | Netherlands Antilles |
| NULL | NULL        | United Arab Emirates |
| NULL | NULL        | Argentina            |
| NULL | NULL        | Armenia              |
+------+-------------+----------------------+
10 rows in set (0.00 sec)

五:字符集

1.定义:

字符集:是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。

2. 查看字符集和校验规则

#查看字符集 mysql> show charset;  

#校验规则 mysql> show collation; 
mysql> show collation where charset='utf8';
+--------------------------+---------+-----+---------+----------+---------+
| Collation                | Charset | Id  | Default | Compiled | Sortlen |
+--------------------------+---------+-----+---------+----------+---------+
| utf8_general_ci          | utf8    |  33 | Yes     | Yes      |       1 |
| utf8_bin                 | utf8    |  83 |         | Yes      |       1 |
| utf8_unicode_ci          | utf8    | 192 |         | Yes      |       8 |
| utf8_icelandic_ci        | utf8    | 193 |         | Yes      |       8 |
| utf8_latvian_ci          | utf8    | 194 |         | Yes      |       8 |
| utf8_romanian_ci         | utf8    | 195 |         | Yes      |       8 |
| utf8_slovenian_ci        | utf8    | 196 |         | Yes      |       8 |
| utf8_polish_ci           | utf8    | 197 |         | Yes      |       8 |
| utf8_estonian_ci         | utf8    | 198 |         | Yes      |       8 |
| utf8_spanish_ci          | utf8    | 199 |         | Yes      |       8 |
| utf8_swedish_ci          | utf8    | 200 |         | Yes      |       8 |
| utf8_turkish_ci          | utf8    | 201 |         | Yes      |       8 |
| utf8_czech_ci            | utf8    | 202 |         | Yes      |       8 |
| utf8_danish_ci           | utf8    | 203 |         | Yes      |       8 |
| utf8_lithuanian_ci       | utf8    | 204 |         | Yes      |       8 |
| utf8_slovak_ci           | utf8    | 205 |         | Yes      |       8 |
| utf8_spanish2_ci         | utf8    | 206 |         | Yes      |       8 |
| utf8_roman_ci            | utf8    | 207 |         | Yes      |       8 |
| utf8_persian_ci          | utf8    | 208 |         | Yes      |       8 |
| utf8_esperanto_ci        | utf8    | 209 |         | Yes      |       8 |
| utf8_hungarian_ci        | utf8    | 210 |         | Yes      |       8 |
| utf8_sinhala_ci          | utf8    | 211 |         | Yes      |       8 |
| utf8_german2_ci          | utf8    | 212 |         | Yes      |       8 |
| utf8_croatian_ci         | utf8    | 213 |         | Yes      |       8 |
| utf8_unicode_520_ci      | utf8    | 214 |         | Yes      |       8 |
| utf8_vietnamese_ci       | utf8    | 215 |         | Yes      |       8 |
| utf8_general_mysql500_ci | utf8    | 223 |         | Yes      |       1 |
+--------------------------+---------+-----+---------+----------+---------+

mysql> show collation like '%cs';
+--------------------+---------+----+---------+----------+---------+
| Collation          | Charset | Id | Default | Compiled | Sortlen |
+--------------------+---------+----+---------+----------+---------+
| latin1_general_cs  | latin1  | 49 |         | Yes      |       1 |
| latin2_czech_cs    | latin2  |  2 |         | Yes      |       4 |
| cp1250_czech_cs    | cp1250  | 34 |         | Yes      |       2 |
| latin7_estonian_cs | latin7  | 20 |         | Yes      |       1 |
| latin7_general_cs  | latin7  | 42 |         | Yes      |       1 |
| cp1251_general_cs  | cp1251  | 52 |         | Yes      |       1 |
+--------------------+---------+----+---------+----------+---------+

ci结尾的校验规则: 不区分大小写
bin和cs结尾的校验规则:严格区分大小写

3. 设置字符集

#操作系统C6
[root@db01 ~]# vim /etc/syscofig/i18n

#操作系统C7
[root@db01 ~]# vim /etc/locale.conf 
LANG="en_US.UTF-8"

#数据库设置字符集
vim /etc/my.cnf
character_set_server=utf8

#建库语句
mysql> create database xxx charset utf8;

#建表语句
mysql> create table xxx(id int)charset utf8;

思考:在生产环境中,字符集不够用

mysql> alter table aaa charset gbk;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0


mysql> show create table aaa;
+-------+--------------------------------------------------------------------------------------+
| Table | Create Table                                                                         |
+-------+--------------------------------------------------------------------------------------+
| aaa   | CREATE TABLE `aaa` (
  `id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk |
+-------+--------------------------------------------------------------------------------------+

在生产中,只能将小的字符集改成大的字符集。

举例子:

latin1       1-5000

utf8         2-65535

gbk          4000-65535

utf8mb4      1-90000

#修改字符集前先要去查询是否有包含的关系,如果有才可以修改,如上:latin1不能改成utf8,可以改成utf8mb4

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

六mysql日志管理

sql中不足六位的补零该怎么写

MySQL语句SQL应用

MYSQL 之 JDBC: PreparedStatement

SQL Select 语句的用法

Mybatis -- 动态Sql概述动态Sql之<if>(包含<where>)动态Sql之<foreach>sql片段抽取