一、 MySQL概念
程序 =数据+指令构成,如果下载1个程序需要连带该程序所有代码+数据下载到本地,那这个程序运行起来势必造成本机内存压力暴涨,所以我们需要1个在远程server端帮我们管理数据的软件,程序通过客户端去连接server端socket,访问服务端数据库管理软件,按需获取和添加数据, 这种管理数据的软件有很多例如MySQL、Oracle、SQLServer.....以下主要介绍MySQL。
MySQL是 一种管理文件(数据库)的软件,客户端程序通过向server端程序发送SQL语句,帮我们创建、查找、管理文件;(不是所有数据都存储在数据库,例如图片、视频只 存放 这些数据的存在硬盘上的路径)
MySQL架构:
客户端软件:(mariadb/mysqld): socket客户端开启,连接MySQL服务端、向服务端发送SQL指令;
服务端软件:(pymsql/navicat......): socket服务端开启,等待客户端发送SQL语句,接收SQL语句、解析、执行,其本质就是操作本地文件;
二、数据库分类
1、关系型数据库 (Oracle、SQLServer、MySQL)
2、非关系型数据库 ( Redis、Memcached)
区别:
关系型数据库: 表与表之间有关联(例如:1对1,1对多、多对多), 数据和数据之间有强类型的关系约束;
非关系型数据库:不使用二维表来表现数据,使用键值对存储,数据和数据无1对1,1对多、多对多关系约束;
二、数据库安装(Mariadb):
1、Linux安装Mariadb
[root@localhost zhanggen]# yum -y install mariadb*
[root@localhost zhanggen]# systemctl restart mariadb
2、设置toot密码
UPDATE user SET Password = password ("123.com") WHERE User = 'root';
3、 刷新认证表
flush privileges;
4、删除默认空白用mysql库user表中空白用户:(注意MySQL安装之后一定要删除空白用户,否则登录Linux之后就可以匿名登录MySQL)
delete from mysql.user where user='';
5、配置文件中配置,启动MySQL跳过数据库文件授权表(忘记密码使用);
skip-grant-tables
三、连接数据库
1、本地连接:mysql -u 用户 -p 密码
[root@localhost zhanggen]# mysql -u root -p Enter password:
2、远程连接:mysql -h IP地址 -P 端口 -u 用户 -p 密码
默认情况下所有用户都无法远程登录Mariadb,需要创建用户+为用户授权;
0.创建用户
MariaDB [(none)]> create user "zhanggen"@'192.%.%.%' identified by '123.com'; Query OK, 0 rows affected (0.00 sec)
1.为已创建的用户授权 MariaDB [(none)]> grant select,insert,update on mysql.* to "zhenggen"@'192.%.%.%'; Query OK, 0 rows affected (0.00 sec)
2.开始远程登录 [root@localhost zhanggen]# mysql -h 192.168.226.128 -P 3306 -u zhanggen -p123.com Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 25
四、数据添加用户和授权操作
默认情况下即使root用户也是无法远程登录MySQL的,需要创建用户和授权;
1、添加用户 alex 现在192.1.1网段登录 密码;
MariaDB [(none)]> create user "zhanggen"@'192.%.%.%' identified by '123.com'; Query OK, 0 rows affected (0.00 sec)
例:
create user "alex"@'192.1.1.%' identified by '11';
create user "alex"@'192.1.1.1%' identified by '11';
2、用户授权:ps:只有root用户才有授权权限
语法格式:
grant all privileges (复用所有权限,指定权限(增、删、改、查) on 数据库.*(所有表)/ 数据库.指定表 to 人 '@' '%'(所有网段) / 指定网段 ;
例:
MariaDB [mysql]> grant all privileges on web.* to "web"@'%.%.%.%'; Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> grant select,insert,update on mysql.* to "zhenggen"@'192.%.%.%'; Query OK, 0 rows affected (0.00 sec)
[root@localhost zhanggen]# mysql -h 192.168.226.128 -P 3306 -u zhanggen -p123.com Welcome to the MariaDB monitor. Commands end with ; or \g.
grant select,insert,update on db2.* to "alex1"@'192.1.1.1%';
3、 删除用户权限
revoke all privileges on mysql.* from "zhanggen"@'192.%.%.%';
创建用户+授权实例:
1、查看授权用户:mysq库下的user表
select host,user from mysql.user;
2、创建用户eric, 可以使用任何网段 % ,指定密码 123123
create user 'eric'@'%' identified by '123123';
3、 授予all privileges全部权限 给eric用户
grant all privileges on *.* to 'eric'@'%';
五、数据库操作:
可以创建数据库和删除数据库但是不可以修改数据库,如果想要修改drop之后重新创建
查看数据库:
MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+
创建数据库并设置默认字符编码:
注意再创建数据库的时候一定要设置charset=utf8,否则MySQL会出现以下报错;
Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MariaDB [(none)]> create database db2 default charset=utf8; Query OK, 1 row affected (0.00 sec)
删除数据库
MariaDB [(none)]> drop database db2; Query OK, 0 rows affected (0.00 sec)
六、库中表操作
1、查看表
show tables;
2、创建表
2.1创建表就是定义表结构(定义表中的列的属性和列里存储数据类型)
2.2、定义表结构格式
create table 表名(
列名 类型 是否可以为空 自增列(auto_increment) 数据类型 主键(primary key) ,
列名 类型 是否可以为空)ENGINE=InnoDB DEFAULT CHARSET=utf8
ps:
a.Mariadb默认使用 InnoDB引擎支持事物操作,注意:MySQL默认不支持,需要指定;
MariaDB [db2]> show create table t1; +-------+----------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+----------------------------------------------------------------------------------------------------------------------+ | t1 | CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL, `name` char(10) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | +-------+----------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.01 sec)
b、数据库ENGINE InnoDB和MyISAM的区别?
MyISAM:支持全文索引(查询频繁的应用)
Innodb: 支持事务处理、外键、行级锁
2.3、表属性解释
MySQL数据类型
MySQL的数据类型大致分为:数值、时间和字符串
bit[(M)]
二进制位(101001),m表示二进制位的长度(1-64),默认m=1
tinyint[(m)] [unsigned] [zerofill]
小整数,数据类型用于保存一些范围的整数数值范围:
有符号:
-128 ~ 127.
无符号:
~ 255
特别的: MySQL中无布尔值,使用tinyint(1)构造。
int[(m)][unsigned][zerofill]
整数,数据类型用于保存一些范围的整数数值范围:
有符号:
-2147483648 ~ 2147483647
无符号:
~ 4294967295
特别的:整数类型中的m仅用于显示,对存储范围无限制。例如: int(5),当插入数据2时,select 时数据显示为: 00002
bigint[(m)][unsigned][zerofill]
大整数,数据类型用于保存一些范围的整数数值范围:
有符号:
-9223372036854775808 ~ 9223372036854775807
无符号:
~ 18446744073709551615
decimal[(m[,d])] [unsigned] [zerofill]
准确的小数值,m是数字总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。
特别的:对于精确数值计算时需要用此类型
decaimal能够存储精确值的原因在于其内部按照字符串存储。
FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。
无符号:
-3.402823466E+38 to -1.175494351E-38,
1.175494351E-38 to 3.402823466E+38
有符号:
1.175494351E-38 to 3.402823466E+38
**** 数值越大,越不准确 ****
DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。
无符号:
-1.7976931348623157E+308 to -2.2250738585072014E-308
2.2250738585072014E-308 to 1.7976931348623157E+308
有符号:
2.2250738585072014E-308 to 1.7976931348623157E+308
**** 数值越大,越不准确 ****
char (m)
char数据类型用于表示固定长度的字符串,可以包含最多达255个字符。其中m代表字符串的长度。
PS: 即使数据小于m长度,也会占用m长度
varchar(m)
varchars数据类型用于变长的字符串,可以包含最多达255个字符。其中m代表该数据类型所允许保存的字符串的最大长度,只要长度小于该最大值的字符串都可以被保存在该数据类型中。
注:虽然varchar使用起来较为灵活,但是从整个系统的性能角度来说,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。因此,用户在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡
text
text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 − 1)个字符。
mediumtext
A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.
longtext
A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.
enum
枚举类型,
An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.)
示例:
CREATE TABLE shirts (
name VARCHAR(40),
size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
);
INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');
set
集合类型
A SET column can have a maximum of 64 distinct members.
示例:
CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
DATE
YYYY-MM-DD(1000-01-01/9999-12-31)
TIME
HH:MM:SS('-838:59:59'/'838:59:59')
YEAR
YYYY(1901/2155)
DATETIME
YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 Y)
TIMESTAMP
YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某时)
是否为空
是否可空,null表示空,非字符串
not null - 不可空
null - 可空
默认值
默认值,创建列时可以指定默认值,当插入数据时如果未主动设置,则自动添加默认值
create table tb1(
nid int not null defalut 2,
num int not null
)
自增列:该列 一定为int数据类型,1无需插入数据,自动增加;
自增,如果为某列设置自增列,插入数据时无需设置此列,默认将自增(表中只能有一个自增列)
create table tb1(
nid int not null auto_increment primary key,
num int null
)
或
create table tb1(
nid int not null auto_increment,
num int null,
index(nid)
)
注意:1、对于自增列,必须是索引(含主键)。
2、对于自增可以设置步长和起始值
show session variables like 'auto_inc%';
set session auto_increment_increment=2;
set session auto_increment_offset=10;
shwo global variables like 'auto_inc%';
set global auto_increment_increment=2;
set global auto_increment_offset=10;
自增
主键:保证数据唯一性,一种特殊的唯一索引,不允许有空值,如果主键使用单个列,则它的值必须唯一,如果是多列,则其组合必须唯一。主键可以是多列;
主键,一种特殊的唯一索引,不允许有空值,如果主键使用单个列,则它的值必须唯一,如果是多列,则其组合必须唯一。
create table tb1(
nid int not null auto_increment primary key,
num int null
)
或
create table tb1(
nid int not null,
num int not null,
primary key(nid,num)
)
主键
外键:用于和其他表建立关联关系,A表一列,包含对B表的内容(一行)的引用 ;外键功能=关联表(节省内存)+约束(保证数据正确)
外键,一个特殊的索引,只能是指定内容
creat table color(
nid int not null primary key,
name char(16) not null
)
create table fruit(
nid int not null primary key,
smt char(32) null ,
color_id int not null,
constraint fk_cc foreign key (color_id) references color(nid)
)
外键
create table t5 (id int auto_increment primary key,name varchar(9));
create table t2(id int,name char(10)) default charset=utf8;
唯一索引:列中定义了所以索引,该列数据唯一,但是可以为空;
1、单列唯一索引+外键:一对一
2、联合唯一索引+外键:
多对多(权限表)(外键+外键)
外键ID 对应 一行数据主键 所以是1对多
多对多关系是关系数据库中两个表之间的一种关系, 该关系中第一个表中的一个行可以与第二个表中的一个或多个行相关。第二个表中的一个行也可以与第一个表中的一个或多个行相关
要表示多对多关系,您必须创建第三个表,该表通常称为联接表,它将多对多关系划分为两个一对多关系。
A表和B表之间 存在 双向1对多(外键)就是 多对多关系(说白了就是A表外键B表,B表也要外键A表)
此 可以引申出第三张表:记录A表和B表得关系
(两列加起来必须唯一,也就是是说一行数据必须唯一)
0. 唯一索引
create table t1(
id int ....,
num int,
xx int,
unique 唯一索引名称 (列名,列名),
constraint ....
)
#
1 1 1
2 1 2
PS:
唯一:
约束不能重复(可以为空)
PS: 主键不能重复(不能为空)
加速查找
1. 外键的变种
a. 用户表和部门表
用户:
1 alex 1
2 root 1
3 egon 2
4 laoyao 3
部门:
1 服务
2 保安
3 公关
===》 一对多
b. 用户表和博客表
用户表:
1 alex
2 root
3 egon
4 laoyao
博客表:
FK() + 唯一
1 /yuanchenqi/ 4
2 /alex3714/ 1
3 /asdfasdf/ 3
4 /ffffffff/ 2
===> 一对一
create table userinfo1(
id int auto_increment primary key,
name char(10),
gender char(10),
email varchar(64)
)engine=innodb default charset=utf8;
create table admin(
id int not null auto_increment primary key,
username varchar(64) not null,
password VARCHAR(64) not null,
user_id int not null,
unique uq_u1 (user_id),
CONSTRAINT fk_admin_u1 FOREIGN key (user_id) REFERENCES userinfo1(id)
)engine=innodb default charset=utf8;
c. 用户表(百合网) 相亲记录表
示例1:
用户表
相亲表
示例2:
用户表
主机表
用户主机关系表
===》多对多
create table userinfo2(
id int auto_increment primary key,
name char(10),
gender char(10),
email varchar(64)
)engine=innodb default charset=utf8;
create table host(
id int auto_increment primary key,
hostname char(64)
)engine=innodb default charset=utf8;
create table user2host(
id int auto_increment primary key,
userid int not null,
hostid int not null,
unique uq_user_host (userid,hostid),
CONSTRAINT fk_u2h_user FOREIGN key (userid) REFERENCES userinfo2(id),
CONSTRAINT fk_u2h_host FOREIGN key (hostid) REFERENCES host(id)
)engine=innodb default charset=utf8;
指定数据库引擎 编码
create table studentds_info(name char(10),sex char(10),age int) engine=innodb default charset=utf8;
2.4、MySQL(表中数据)数据类型
MySQL的数据类型大致分为:数值、时间和字符串
bit[(M)]
二进制位(101001),m表示二进制位的长度(1-64),默认m=1
tinyint[(m)] [unsigned] [zerofill]
小整数,数据类型用于保存一些范围的整数数值范围:
有符号:
-128 ~ 127.
无符号:
~ 255
特别的: MySQL中无布尔值,使用tinyint(1)构造。
int[(m)][unsigned][zerofill]
整数,数据类型用于保存一些范围的整数数值范围:
有符号:
-2147483648 ~ 2147483647
无符号:
~ 4294967295
特别的:整数类型中的m仅用于显示,对存储范围无限制。例如: int(5),当插入数据2时,select 时数据显示为: 00002
bigint[(m)][unsigned][zerofill]
大整数,数据类型用于保存一些范围的整数数值范围:
有符号:
-9223372036854775808 ~ 9223372036854775807
无符号:
~ 18446744073709551615
decimal[(m[,d])] [unsigned] [zerofill]
准确的小数值,m是数字总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。
特别的:对于精确数值计算时需要用此类型
decaimal能够存储精确值的原因在于其内部按照字符串存储。
FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。
无符号:
-3.402823466E+38 to -1.175494351E-38,
1.175494351E-38 to 3.402823466E+38
有符号:
1.175494351E-38 to 3.402823466E+38
**** 数值越大,越不准确 ****
DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。
无符号:
-1.7976931348623157E+308 to -2.2250738585072014E-308
2.2250738585072014E-308 to 1.7976931348623157E+308
有符号:
2.2250738585072014E-308 to 1.7976931348623157E+308
**** 数值越大,越不准确 ****
char (m)
char数据类型用于表示固定长度的字符串,可以包含最多达255个字符。其中m代表字符串的长度。
PS: 即使数据小于m长度,也会占用m长度
varchar(m)
varchars数据类型用于变长的字符串,可以包含最多达255个字符。其中m代表该数据类型所允许保存的字符串的最大长度,只要长度小于该最大值的字符串都可以被保存在该数据类型中。
注:虽然varchar使用起来较为灵活,但是从整个系统的性能角度来说,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。因此,用户在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡
text
text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 − 1)个字符。
mediumtext
A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.
longtext
A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.
enum
枚举类型,
An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.)
示例:
CREATE TABLE shirts (
name VARCHAR(40),
size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
);
INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');
set
集合类型
A SET column can have a maximum of 64 distinct members.
示例:
CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
DATE
YYYY-MM-DD(1000-01-01/9999-12-31)
TIME
HH:MM:SS('-838:59:59'/'838:59:59')
YEAR
YYYY(1901/2155)
DATETIME
YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 Y)
TIMESTAMP
YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某时)
3、删除表:
a、删除表格(表和表中数据全部消失)
drop table t3;
PS:有时候使用Django的makemigrations+migrate删表时,可能会出现错误,没事自己去数据库里删!
# login_logs=models.ForeignKey(Login_logs,null=True,blank=True,default=None,verbose_name='操作日志,默认为空') # # '''' mysql> drop table DBshow_login_logs; ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails 出错了!! mysql> drop table DBshow_redis_connect; #先删除Django ORM中 有ForeignKey的字段的表( 其他表中没有字段通过外键 ---->指向我表里的ID时,我这张表才可以被删除哦!)
Query OK, 0 rows affected (0.03 sec) mysql> drop table DBshow_login_logs;
b、清空表格中的内容
delete from t3;(自增列不会归零) truncate table t3;(自增列会归零)
4、aleter 修改表结构
a.在原有列基础上增加1列
alter table zhanggen add sex char(10);
b.修改列属性
alter table zhanggen modify name int;
ps:
https://www.cnblogs.com/hellojesson/p/6025548.html
七、表中数据操作
1、查看表结构
desc t4;
2、在表中插入数据(增):
insert into t4(id2,name) values(1,"alex");
3、删除表中数据(删)
delete from t4 where id2=1 and name="alex";
4、修改表中数据
update t4 set name="张根" where id2=4;
5、查找表中数据
select * from t4;
SELECT COUNT(1) FROM day61.user;查看一共有多少行
6、高级查找方法
a、条件查找
select
*
from
表
where
id > 1
and
name
!=
'alex'
and
num = 12;
select
*
from
表
where
id
between
5
and
16;
select
*
from
表
where
id
in
(11,22,33)
select
*
from
表
where
id
not
in
(11,22,33)
select
*
from
表
where
id
in
(
select
nid
from
表)
b、通配符查找
select
*
from
表
where
name
like
'ale%'
- ale开头的所有(多个字符串)
select
*
from
表
where
name
like
'ale_'
- ale开头的所有(一个字符)
c、分页查找
select
*
from
表 limit 5; - 前5行
select
*
from
表 limit 4,5; - 从第4行开始的5行
select
*
from
表 limit 5 offset 4 - 从第4行开始的5行
d、查找排序
select
*
from
表
order
by
列
asc
- 根据 “列” 从小到大排列
select
*
from
表
order
by
列
desc
- 根据 “列” 从大到小排列
select
*
from
表
order
by
列1
desc
,列2
asc
- 根据 “列1” 从大到小排列,如果相同则按列2从小到大排序
e、分组查找
分组: select max(age) group by 列(就是把字段相同的 归为1组)
就是先按相同的分组,然后通过聚合函数,求出每1组中最大/最小的;
select
num
from
表
group
by
num
select
num,nid
from
表
group
by
num,nid
select
num,nid
from
表
where
nid > 10
group
by
num,nid
order
nid
desc
select
num,nid,
count
(*),
sum
(score),
max
(score),
min
(score)
from
表
group
by
num,nid
select
num
from
表
group
by
num
having
max
(id) > 10
特别的:
group
by
必须在
where
之后,
order
by
之前
F、多表连接查询
1、左右连接:
卡槽相接 严丝合缝结合在一起,的前提两者必须有关系;
连表SQL分为: left join 、right join 、inner join,他们之间有何种区别?
left join(左联接) : 返回包括左表中的所有记录和右表中联结字段相等的记录;左侧表是大爷
right join(右联接) : 返回包括右表中的所有记录和左表中联结字段相等的记录;右侧表是大爷
inner join(等值连接) : 只返回两个表中联结字段相等的行; 左侧右侧公正
select * from student left join class on student.class_id=class.cid; select * from course left join teacher on course.cid=teacher.tid; select * from score left join student on score.sid=student.sid left join course on score.corse_id=course.cid;
2、上下连接
union 上下连表(相同去重,不同相加显示)
1、相同列:
SELECT sname FROM student
UNION
SELECT sname FROM student;
2、不同列:(注意上下连接是相连的列数,必须相等)
SELECT sid FROM score
UNION
SELECT sname FROM student;
(列1),(列2)
SELECT sid,num FROM score
UNION
SELECT sid,gender FROM student;
G、临时表(保存临时查询结果) 和查询结果 当做列显示
SELECT
student_id,
(子查询)
(select num from score as s2 where s2.student_id=s1.student_id and course_id = 1) as 语文,
(子查询)
(select num from score as s2 where s2.student_id=s1.student_id and course_id = 2) as 数学,
(子查询)
(select num from score as s2 where s2.student_id=s1.student_id and course_id = 3) as 英语
from score as s1;
H、SQL条件判断语句 : case when score.num > 60 then 1 else 0 END
按各科平均成绩从低到高和及格率的百分数从高到低顺序;
1 思路:case when .. then 2 select course_id, avg(num) as avgnum,sum(case when score.num > 60 then 1 else 0 END)/count(1)*100 as percent from score group by course_id order by avgnum asc,percent desc;
I、笛卡尔积 显示效果
J、SQL三元表达式:
1=1 if print("y") else print("n")
pythonSQL三元表达式
y=1
n=2
print(y) if y>n else print(n)
出处:http://www.cnblogs.com/wupeiqi/
SQL查询练习题
http://www.cnblogs.com/wupeiqi/p/5748496.html
导出现有数据库数据:
mysqldump -u用户名 -p密码 数据库名称 >导出文件路径 # 数据库结构+数据
[root@cmdb ~]# mysqldump -uwebproject -pweb web >/root/web.sql
mysqldump -u用户名 -p密码 -d 数据库名称 >导出文件路径 # 数据库结构,不包含数据
导入现有数据库数据:
create database web charset=utf8; 创建数据库
mysqldump -uwebproject -pweb web >/web.sql
scp /webdb.sql [email protected]:/root/
use web;
source /root/web.sql;
mysql -h localhost -u root -p web < /home/zhanggen/Desktop/web.spl 把文件导入数据库
2、查询“生物”课程比“物理”课程成绩高的所有学生的学号; 思路: 获取所有有生物课程的人(学号,成绩) - 临时表 获取所有有物理课程的人(学号,成绩) - 临时表 根据【学号】连接两个临时表: 学号 物理成绩 生物成绩 然后再进行筛选 select A.student_id,sw,ty from (select student_id,num as sw from score left join course on score.course_id = course.cid where course.cname = '生物') as A left join (select student_id,num as ty from score left join course on score.course_id = course.cid where course.cname = '体育') as B on A.student_id = B.student_id where sw > if(isnull(ty),0,ty); 3、查询平均成绩大于60分的同学的学号和平均成绩; 思路: 根据学生分组,使用avg获取平均值,通过having对avg进行筛选 select student_id,avg(num) from score group by student_id having avg(num) > 60 4、查询所有同学的学号、姓名、选课数、总成绩; select score.student_id,sum(score.num),count(score.student_id),student.sname from score left join student on score.student_id = student.sid group by score.student_id 5、查询姓“李”的老师的个数; select count(tid) from teacher where tname like '李%' select count(1) from (select tid from teacher where tname like '李%') as B 6、查询没学过“叶平”老师课的同学的学号、姓名; 思路: 先查到“李平老师”老师教的所有课ID 获取选过课的所有学生ID 学生表中筛选 select * from student where sid not in ( select DISTINCT student_id from score where score.course_id in ( select cid from course left join teacher on course.teacher_id = teacher.tid where tname = '李平老师' ) ) 7、查询学过“001”并且也学过编号“002”课程的同学的学号、姓名; 思路: 先查到既选择001又选择002课程的所有同学 根据学生进行分组,如果学生数量等于2表示,两门均已选择 select student_id,sname from (select student_id,course_id from score where course_id = 1 or course_id = 2) as B left join student on B.student_id = student.sid group by student_id HAVING count(student_id) > 1 8、查询学过“叶平”老师所教的所有课的同学的学号、姓名; 同上,只不过将001和002变成 in (叶平老师的所有课) 9、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名; 同第1题 10、查询有课程成绩小于60分的同学的学号、姓名; select sid,sname from student where sid in ( select distinct student_id from score where num < 60 ) 11、查询没有学全所有课的同学的学号、姓名; 思路: 在分数表中根据学生进行分组,获取每一个学生选课数量 如果数量 == 总课程数量,表示已经选择了所有课程 select student_id,sname from score left join student on score.student_id = student.sid group by student_id HAVING count(course_id) = (select count(1) from course) 12、查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名; 思路: 获取 001 同学选择的所有课程 获取课程在其中的所有人以及所有课程 根据学生筛选,获取所有学生信息 再与学生表连接,获取姓名 select student_id,sname, count(course_id) from score left join student on score.student_id = student.sid where student_id != 1 and course_id in (select course_id from score where student_id = 1) group by student_id 13、查询至少学过学号为“001”同学所有课的其他同学学号和姓名; 先找到和001的学过的所有人 然后个数 = 001所有学科 ==》 其他人可能选择的更多 select student_id,sname, count(course_id) from score left join student on score.student_id = student.sid where student_id != 1 and course_id in (select course_id from score where student_id = 1) group by student_id having count(course_id) = (select count(course_id) from score where student_id = 1) 14、查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名; 个数相同 002学过的也学过 select student_id,sname from score left join student on score.student_id = student.sid where student_id in ( select student_id from score where student_id != 1 group by student_id HAVING count(course_id) = (select count(1) from score where student_id = 1) ) and course_id in (select course_id from score where student_id = 1) group by student_id HAVING count(course_id) = (select count(1) from score where student_id = 1) 15、删除学习“叶平”老师课的score表记录; delete from score where course_id in ( select cid from course left join teacher on course.teacher_id = teacher.tid where teacher.name = '叶平' ) 16、向SC表中插入一些记录,这些记录要求符合以下条件:①没有上过编号“002”课程的同学学号;②插入“002”号课程的平均成绩; 思路: 由于insert 支持 inset into tb1(xx,xx) select x1,x2 from tb2; 所有,获取所有没上过002课的所有人,获取002的平均成绩 insert into score(student_id, course_id, num) select sid,2,(select avg(num) from score where course_id = 2) from student where sid not in ( select student_id from score where course_id = 2 ) 17、按平均成绩从低到高 显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分; select sc.student_id, (select num from score left join course on score.course_id = course.cid where course.cname = "生物" and score.student_id=sc.student_id) as sy, (select num from score left join course on score.course_id = course.cid where course.cname = "物理" and score.student_id=sc.student_id) as wl, (select num from score left join course on score.course_id = course.cid where course.cname = "体育" and score.student_id=sc.student_id) as ty, count(sc.course_id), avg(sc.num) from score as sc group by student_id desc 18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分; select course_id, max(num) as max_num, min(num) as min_num from score group by course_id; 19、按各科平均成绩从低到高和及格率的百分数从高到低顺序; 思路:case when .. then select course_id, avg(num) as avgnum,sum(case when score.num > 60 then 1 else 0 END)/count(1)*100 as percent from score group by course_id order by avgnum asc,percent desc; 20、课程平均分从高到低显示(现实任课老师); select avg(if(isnull(score.num),0,score.num)),teacher.tname from course left join score on course.cid = score.course_id left join teacher on course.teacher_id = teacher.tid group by score.course_id 21、查询各科成绩前三名的记录:(不考虑成绩并列情况) select score.sid,score.course_id,score.num,T.first_num,T.second_num from score left join ( select sid, (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0,1) as first_num, (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 3,1) as second_num from score as s1 ) as T on score.sid =T.sid where score.num <= T.first_num and score.num >= T.second_num 22、查询每门课程被选修的学生数; select course_id, count(1) from score group by course_id; 23、查询出只选修了一门课程的全部学生的学号和姓名; select student.sid, student.sname, count(1) from score left join student on score.student_id = student.sid group by course_id having count(1) = 1 24、查询男生、女生的人数; select * from (select count(1) as man from student where gender='男') as A , (select count(1) as feman from student where gender='女') as B 25、查询姓“张”的学生名单; select sname from student where sname like '张%'; 26、查询同名同姓学生名单,并统计同名人数; select sname,count(1) as count from student group by sname; 27、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列; select course_id,avg(if(isnull(num), 0 ,num)) as avg from score group by course_id order by avg asc,course_id desc; 28、查询平均成绩大于85的所有学生的学号、姓名和平均成绩; select student_id,sname, avg(if(isnull(num), 0 ,num)) from score left join student on score.student_id = student.sid group by student_id; 29、查询课程名称为“数学”,且分数低于60的学生姓名和分数; select student.sname,score.num from score left join course on score.course_id = course.cid left join student on score.student_id = student.sid where score.num < 60 and course.cname = '生物' 30、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名; select * from score where score.student_id = 3 and score.num > 80 31、求选了课程的学生人数 select count(distinct student_id) from score select count(c) from ( select count(student_id) as c from score group by student_id) as A 32、查询选修“杨艳”老师所授课程的学生中,成绩最高的学生姓名及其成绩; select sname,num from score left join student on score.student_id = student.sid where score.course_id in (select course.cid from course left join teacher on course.teacher_id = teacher.tid where tname='张磊老师') order by num desc limit 1; 33、查询各个课程及相应的选修人数; select course.cname,count(1) from score left join course on score.course_id = course.cid group by course_id; 34、查询不同课程但成绩相同的学生的学号、课程号、学生成绩; select DISTINCT s1.course_id,s2.course_id,s1.num,s2.num from score as s1, score as s2 where s1.num = s2.num and s1.course_id != s2.course_id; 35、查询每门课程成绩最好的前两名; select score.sid,score.course_id,score.num,T.first_num,T.second_num from score left join ( select sid, (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0,1) as first_num, (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 1,1) as second_num from score as s1 ) as T on score.sid =T.sid where score.num <= T.first_num and score.num >= T.second_num 36、检索至少选修两门课程的学生学号; select student_id from score group by student_id having count(student_id) > 1 37、查询全部学生都选修的课程的课程号和课程名; select course_id,count(1) from score group by course_id having count(1) = (select count(1) from student); 38、查询没学过“叶平”老师讲授的任一门课程的学生姓名; select student_id,student.sname from score left join student on score.student_id = student.sid where score.course_id not in ( select cid from course left join teacher on course.teacher_id = teacher.tid where tname = '张磊老师' ) group by student_id 39、查询两门以上不及格课程的同学的学号及其平均成绩; select student_id,count(1) from score where num < 60 group by student_id having count(1) > 2 40、检索“004”课程分数小于60,按分数降序排列的同学学号; select student_id from score where num< 60 and course_id = 4 order by num desc; 41、删除“002”同学的“001”课程的成绩; delete from score where course_id = 1 and student_id = 2
参考
参考