码迷,mamicode.com
首页 > 数据库 > 详细

SQL基础应用

时间:2020-05-20 00:22:19      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:多表连接   方式   where   alter   空值   lap   结构化   cat   需求   

1mysql内置的功能

1.1 连接数据库

mysql常用参数:
-u? ? ? ? ? ? ?
用户
-p? ? ? ? ? ? ?
密码
-h? ? ? ? ? ? ?IP
-P? ? ? ? ? ? ?
端口
-S? ? ? ? ? ? ?socket
文件
-e? ? ? ? ? ? ?
免交互执行命令
<? ? ? ? ? ? ?
导入SQL脚本

例子:

  1. mysql -uroot -p -S /tmp/mysql.sock
  2. mysql -uroot -p -h10.0.0.51 -P3306
  3. -e 免交互执行sql语句

[root@db01 ~]# mysql -uroot -p -e "show databases;"

技术图片

  1. < 恢复数据
    [root@db01 ~]# mysql -uroot -p123 < /root/world.sql
    1.2
    内置命令
    help
    打印mysql帮助
    \c ctrl+c
    结束上个命令运行
    \q quit; exit; ctrl+d
    退出mysql
    \G
    将数据竖起来显示
    source
    恢复备份文件(source /root/world.sql)

2SQL基础应用

2.1 SQL介绍

结构化的查询语言
关系型数据库通用的命令
遵循SQL92的标准(SQL_MODE)

2.2 SQL常用种类

DDL 数据定义语言 ???? create drop
DCL
数据控制语言 grant revoke
DML
数据操作语言 insert update delete
DQL
数据查询语言???? select show

3SQL引入-数据库的逻辑结构


库名字
库属性:字符集,排序规则


表名
表属性:存储引擎类型,字符集,排序规则
列名
列属性:数据类型,约束,其他属性
数据行

4、字符集 (charset)

相当于MySQL的密码本(编码表)

show charset;
utf8 : 3
个字节
utf8mb4 (
建议): 4个字节,支持emoji

5、排序规则: collation

mysql> show collation;

对于英文字符串的,大小写的敏感
utf8mb4generalci
大小写不敏感
utf8mb4_bin
大小写敏感(存拼音,日文)

6、数据类型介绍

6.1 作用

保证数据的正确性和标准性

6.2 数值类型

整数
tinyint
-128~127
int
-231~231-1
浮点数

技术图片

说明:手机号是无法存储到int的。一般是使用char类型来存储收集号

6.3 字符类型

char(100)
定长字符串类型,不管字符串长度多长,都立即分配100个字符长度的存储空间,未占满的空间使用"空格"填充
varchar(100)
变长字符串类型,每次存储数据之前,都要先判断一下长度,按需分配此盘空间.
会单独申请一个字符长度的空间存储字符长度(少于255,如果超过255以上,会占用两个存储空间)

如何选择这两个数据类型?

  1. 少于255个字符串长度,定长的列值,选择char
  2. 多于255字符长度,变长的字符串,可以选择varchar

enum 枚举数据类型
address enum(‘sz‘,‘sh‘,‘bj‘.....)
1 2 3
悬念,以上数据类型可能会影响到索引的性能

技术图片

6.4 时间类型

datetime
范围为从 1000-01-01 00:00:00.000000 9999-12-31 23:59:59.999999
timestamp
范围为从 1970-01-01 00:00:00.000000 2038-01-19 03:14:07.999999

技术图片

列值不能为空,也是表设计的规范,尽可能将所有的列设置为非空。可以设置默认值为0
unique key
:唯一键
列值不能重复
unsigned
:无符号
针对数字列,非负数。

其他属性:
key :
索引
可以在某列上建立索引,来优化查询

6.5 二进制类型

技术图片

7DDL 数据定义语言的应用

7.1 DDL-库的定义

7.1.1 创建数据库

CREATE DATABASE zabbix CHARSET utf8mb4 COLLATE utf8mb4_bin;

7.1.2 查看库情况

SHOW DATABASES;
SHOW CREATE DATABASE zabbix;

7.1.3 删除数据库(记住:不要在生产环境中操作)

DROP DATABASE syxk;

7.1.4 修改数据库字符集

注意: 一定是从小往大了改,比如utf8--->utf8mb4.
目标字符集一定是源字符集的严格超级.
CREATE DATABASE syxk;
SHOW CREATE DATABASE syxk;
ALTER DATABASE syxk CHARSET utf8mb4;

7.1.5 关于库定义规范 *

1.库名使用小写字符
2.
库名不能以数字开头
3.
不能是数据库内部的关键字
4.
必须设置字符集.

7.2 DDL-表的定义

表名,列名,列属性,表属性

7.2.1 语法格式

create table stu(
1 属性(数据类型、约束、其他属性),
2 属性,
3 属性
)

7.2.2 列属性

PRIMARY KEY : 主键约束,表中只能有一个,非空且唯一.
NOT NULL :
非空约束,不允许空值
UNIQUE KEY :
唯一键约束,不允许重复值
DEFAULT :
一般配合 NOT NULL 一起使用.
UNSIGNED :
无符号,针对数字列,非负数
COMMENT :
注释
AUTO_INCREMENT :
自增长的列

7.2.3 建表规范 *

1. 表名小写字母,不能数字开头,
2.
不能是保留字符,使用和业务有关的表名
3.
选择合适的数据类型及长度
4.
每个列设置 NOT NULL + DEFAULT .对于数据0填充,对于字符使用有效字符串填充
5.
没个列设置注释
6.
表必须设置存储引擎和字符集
7.
主键列尽量是无关列数字列,最好是自增长
8. enum
类型不要保存数字,只能是字符串类型

7.2.4 建表

CREATE TABLE stu (
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT ‘
学号‘,
sname VARCHAR(255) NOT NULL COMMENT ‘
姓名‘,
age TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT ‘
年龄‘,
gender ENUM(‘m‘,‘f‘,‘n‘) NOT NULL DEFAULT ‘n‘ COMMENT ‘
性别‘,
intime DATETIME NOT NULL DEFAULT NOW() COMMENT ‘
入学时间
)ENGINE INNODB CHARSET utf8mb4 COMMENT ‘
学生表‘;

7.2.5 查询建表信息

SHOW TABLES;
SHOW CREATE TABLE stu;
DESC stu; #
查看表结构

7.2.6 创建一个表结构一样的表

CREATE TABLE test LIKE stu;

7.2.7 删表(生产中禁用命令,危险!)

DROP TABLE test;

7.2.8 修改表

1.stu表中添加qq
DESC stu;
ALTER TABLE stu ADD qq VARCHAR(20) NOT NULL COMMENT ‘qq
‘;

2.sname后加微信列
ALTER TABLE stu ADD wechat VARCHAR(64) NOT NULL UNIQUE COMMENT ‘
微信号‘ AFTER sname;

3.id列前加一个新列num
ALTER TABLE stu ADD num INT NOT NULL UNIQUE COMMENT ‘
身份证‘ FIRST ;
DESC stu;

4.把刚才添加的列都删掉(危险,生产中禁用操作)
ALTER TABLE stu DROP num;
DESC stu;
ALTER TABLE stu DROP qq;
ALTER TABLE stu DROP wechat;

5.修改sname数据类型的属性
DESC stu;
ALTER TABLE stu MODIFY sname VARCHAR(64) NOT NULL COMMENT ‘
姓名‘;

6.gender 改为 sex 数据类型改为 CHAR 类型 ***
ALTER TABLE stu CHANGE gender sex CHAR(4) NOT NULL COMMENT ‘
性别‘;

说明:修改字符集,修改后的字符集一定是原字符集的严格超集

7.2.9 注意事项

情况1ALTER 语句是在原有数据的表中增加一个列,是需要对表结构进行更改,如果在生产环境中,这个表有可能是在频繁的访问的,还可能有一堆的业务过来,比如往里面插入行(增删改查),这种在线更改的DDL语句,是会进行锁表操作的。也就是这种语句是不合适在一个繁忙的时刻操作的(一定要避开生产的繁忙时刻) (建议:避开业务繁忙期)

情况 2:若紧急上线。操作流程

方式一:先将表的数据创建一个临时表,就是一模一样的表,copy出来(copy是不会锁表的,等于复制了一份,生成一个临时表)。然后进行临时表的变更,最后对原表进行替换。

方式二:pt-osc (工具)进行在线DDL,解决锁表的时间(另外8.0版本已经解决了这个问题)

?

8DCL 数据控制语言的应用

8.1 grant

mysql> grant SELECT,INSERT,UPDATE,DELETE on wordpress.* to wordpress@‘10.0.0.%‘ identified by ‘123‘;

8.2 revoke

mysql> revoke delete on wordpress.* from ‘wordpress‘@‘10.0.0.%‘;
mysql> show grants for wordpress@‘10.0.0.%‘;

9DML 数据操作语言的应用

9.1 insert

DESC stu;

技术图片

1.最偷懒
INSERT stu VALUES(1,‘zs‘,18,‘m‘,NOW());
SELECT * FROM stu;

2.最规范
INSERT INTO stu(id,sname,age,sex,intime)
VALUES (2,‘ls‘,19,‘f‘,NOW());

3.针对性的录入数据
INSERT INTO stu(sname,age,sex)
VALUES (‘w5‘,11,‘m‘);

4.一次性录入多行
INSERT INTO stu(sname,age,sex)
VALUES
(‘aa‘,11,‘m‘),
(‘bb‘,12,‘f‘),
(‘cc‘,13,‘m‘);

9.2 update(一定要加where条件)

UPDATE stu SET sname=‘aaa‘;
SELECT * FROM stu;
UPDATE stu SET sname=‘bb‘ WHERE id=6;

9.3 delete (一定要有where条件)(危险!)

DELETE FROM stu;
DELETE FROM stu WHERE id=9;

生产中屏蔽delete功能
使用update替代delete
ALTER TABLE stu ADD isdel TINYINT DEFAULT 0 ;
UPDATE stu SET isdel=1 WHERE id=7;
SELECT * FROM stu WHERE is_del=0;

10DQL 数据查询语言应用

select
show

10.1 select 语句的应用

10.1.1 select单独使用的情况

mysql> select @@basedir; #查看软件安装目录
mysql> select @@port; #
查看当前数据库的端口
mysql> select @@innodb_flush_log_at_trx_commit;
mysql> show variables like ‘innodb%‘; #
模糊查询
mysql> select database(); #
查看当前的库
mysql> select now(); #
查看当前的时间

10.1.2 select通用语法(单表)

select 1,2 from where 条件 group by 条件 having 条件 order by 条件 limit

select user,count(name) from where group by user having order by limit;

语句顺序即如下:(不能乱) 可以单独使用.但这个顺序不能乱,不然语法错误。
select

from

where
条件
group by
条件
having
条件
order by
条件
limit

10.1.3 练习环境的说明

World 数据库
city
城市表
country
国家表
countrylanguage
国家的语言

city表结构 desc city;


技术图片

ID : 城市序号/ID(1-...)
name :
城市名字
countrycode :
国家代码,例如:CHN,USA
district :
区域: 中国 美国
population :
人口数

如何熟悉数据库业务?

  1. 快速和研发人员打好关系 (方式/方法)
  2. 找到领导要ER (表与表之间有连接关系,及多表关联)
  3. DESC ,show create table
  4. select * from city limit 5; 而要注意:select * from city (这个命令不要在生产环境中使用)

10.1.4 SELECT 配合FROM子句使用

select ,, from
例子:

  1. 查询表中所有的信息(生产中几乎是没有这种需求的)
    USE world ;
    SELECT id,NAME ,countrycode ,district,population FROM city;
    或者:
    SELECT * FROM city;
    (这个命令最好不要在生产环境中使用)
  2. 查询表中 namepopulation的值
    SELECT NAME ,population FROM city;

10.1.5 SELECT 配合WHERE 子句使用

select ,, from where 过滤条件

  1. 查询中国所有的城市名和人口数
    SELECT NAME,population FROM city
    WHERE countrycode=‘CHN‘;

  2. 世界上小于100人的城市名和人口数
    SELECT NAME,population FROM city

  1. 查询中国人口数量大于1000w的城市名和人口
    SELECT NAME,population FROM city
    WHERE countrycode=‘CHN‘ AND population>8000000;

    查询中国或美国的城市名和人口数
    SELECT NAME,population FROM city
    WHERE countrycode=‘CHN‘ OR countrycode=‘USA‘;

    查询人口数量在500w600w之间的城市名和人口数
    SELECT NAME,population FROM city
    WHERE population>5000000 AND population<6000000;
    或者:
    SELECT NAME,population FROM city
    WHERE population BETWEEN 5000000 AND 6000000;

  2. 查询一下contrycode中带有CH开头,城市信息

    SELECT * FROM city
    WHERE countrycode LIKE ‘CH%‘;

注意:不要出现类似于 %CH%,前后都有百分号的语句,因为不走索引,性能极差
如果业务中有大量需求,我们用"ES(数据库)"来替代

  1. where 配合 in 语句

例子:

查询中国或美国的城市信息.
SELECT NAME,population FROM city
WHERE countrycode=‘CHN‘ OR countrycode=‘USA‘;
或者:
SELECT NAME,population FROM city
WHERE countrycode IN (‘CHN‘ ,‘USA‘);

10.1.6 SELECT 配合GROUP BY 子句使用

作用:根据 by后面的条件进行分组,方便统计,by后面跟一个列或多个列。
常用的聚合函数:
max()
:最大值
min()
:最小值
avg()
:平均值
sum()
:总和
count()
:个数
group_concat():
该函数返回带有来自一个组的连接的非NULL值的字符串结果。(列转行) 在数据表中1对多是不允许的。如:
name age
张三 14
张三 15
在实际生活中,类似这种重名的现象是有的。但将其转为1行显示,及
name age
张三 14,15
这一种现象是不被允许的,在数据表中都是11的关系存储。遇见这类情况就需要使用到聚合函数group_concat().
GROUP BY +
聚合函数公式:
1.
遇到统计想函数
2.
形容词前 GROUP BY
3.
函数中央是名词
4.
列名select后添加

GROUP BY将某列中有共同条件的数据行,分成一组,然后在进行聚合函数操作.
例子:

  1. 统计每个国家城市的个数
    SELECT countrycode ,COUNT(id) FROM city
    GROUP BY countrycode;
  2. 统计每个国家的总人口数.
    SELECT countrycode,SUM(population) FROM city
    GROUP BY countrycode;
  3. 统计每个国家省 的个数
    SELECT countrycode,COUNT(DISTINCT district) FROM city
    GROUP BY countrycode; #
    说明:第一个 DISTINCT 去重 第二个 district 省份
  4. 统计中国每个省的总人口数
    SELECT district, SUM(population) FROM city
    WHERE countrycode=‘CHN‘
    GROUP BY district ;
  5. 统计中国每个省城市的个数
    SELECT district, COUNT(NAME) FROM city
    WHERE countrycode=‘CHN‘
    GROUP BY district ;
  6. 统计中国每个省城市的名字列表 guangdong guangzhou,shenzhen,foshan.... (使用GROUP_CONCAT()
  1. 小扩展

10.1.7 SELECT 配合HAVING子句使用

语句顺序:where之后是group之后是having.不能是having之后有group

例子:

1.统计所有国家的总人口数量,将总人口数大于1亿的过滤出来。

SELECT countrycode.SUM(population) FROM city GROUP BY countrycode

HAVING SUM(population)>100000000;

10.1.8 SELECT 配合ORDER BY子句使用

例子:

  1. 统计所有国家的总人口数量,
    将总人口数大于5000w的过滤出来,
    并且按照从大到小顺序排列
    SELECT countrycode,SUM(population) FROM city
    GROUP BY countrycode
    HAVING SUM(population)>50000000
    ORDER BY SUM(population) DESC ;

DESC :从大到小

ASC : 从小到大

10.1.9 SELECT 配合LIMIT子句使用

例子:

  1. 统计所有国家的总人口数量,将总人口数大于5000w的过滤出来,并且按照从大到小顺序排列,只显示前三名.

SELECT countrycode,SUM(population) FROM city
GROUP BY countrycode
HAVING SUM(population)>50000000
ORDER BY SUM(population) DESC
LIMIT 3;

SELECT countrycode,SUM(population) FROM city
GROUP BY countrycode
HAVING SUM(population)>50000000
ORDER BY SUM(population) DESC
LIMIT 3,3; #
跳过前三行(从第四行开始),一共显示三行。

SELECT countrycode,SUM(population) FROM city
GROUP BY countrycode
HAVING SUM(population)>50000000
ORDER BY SUM(population) DESC
LIMIT 3 OFFSET 3;

LIMIT M,N : 跳过M,显示一共N
LIMIT Y OFFSET X:
跳过X,显示一共Y

10.1.10 练习题

  1. 统计中国每个省的总人口数,只打印总人口数小于100w
    SELECT district ,SUM(population) FROM city
    WHERE countrycode=‘CHN‘
    GROUP BY district
    HAVING SUM(population)<1000000;
  2. 查看中国所有的城市,并按人口数进行排序(从大到小)
    SELECT * FROM city WHERE countrycode=‘CHN‘
    ORDER BY population DESC;
  3. 统计中国各个省的总人口数量,按照总人口从大到小排序
    SELECT district ,SUM(population) FROM city
    WHERE countrycode=‘CHN‘
    GROUP BY district
    ORDER BY SUM(population) DESC ;
  1. 统计中国,每个省的总人口,找出总人口大于500w,并按总人口从大到小排序,只显示前三名
    SELECT district ,SUM(population) FROM city
    WHERE countrycode=‘CHN‘
    GROUP BY district
    HAVING SUM(population)>5000000
    ORDER BY SUM(population) DESC
    LIMIT 3;

10.1.11 小结

统计中国每个省的城市个数,只要大于10个的,从大到小排序前三名。

select disctrict , count(name) from city
where countrycode=‘CHN‘
group by district
having count(name) >10
order by count(name) desc
limit 3;

10.1.12 distinct:去重复

mysql> SELECT countrycode FROM city ;

mysql> SELECT DISTINCT(countrycode) FROM city ;

mysql> select count(distinct countrycode) from city;

10.1.13 union union all

作用: 多个结果集合并查询的功能

需求: 查询中国或者美国的城市信息
SELECT * FROM city WHERE countrycode=‘CHN‘ OR countrycode=‘USA‘;

改写为:
SELECT * FROM city WHERE countrycode=‘CHN‘
UNION ALL
SELECT * FROM city WHERE countrycode=‘USA‘;

说明:union union all 的区别 ?
union
去重复
union all
不去重复

说明:一般情况下,我们会将IN或者OR语句改写成UNION ALL,来提高性能。

10.1.14 使用concat()函数拼接语句或命令

1mysql> select concat(user,"@",host) from mysql.user;

10.2 Show语句的应用

show databases; ???? 查看数据库名

show tables; ???????? ???? 查看表名

show create database xx; ???? 查看建库语句

show create table xx;???? 查看建表语句

show processlist;???????? 查看所有用户连接情况

show charset;???????? 查看支持的字符集

show collation;???????? 查看所有支持的校对规则

show grants for xx;???? 查看用户的权限信息

show variables like ‘%xx%‘ 查看参数信息

show engines;???????? 查看所有支持的存储引擎类型

show index from xxx???? 查看表的索引信息

show engine innodb status\G 查看innoDB引擎详细状态信息

show binary logs ???? 查看二进制日志的列表信息

show binlog events in ‘‘???? 查看二进制日志的事件信息

show master status ;???? 查看mysql当前使用二进制日志信息

show slave status\G 查看从库状态信息

show relaylog events in ‘‘ ???? 查看中继日志的事件信息

show status like ‘‘???????? 查看数据库整体状态信息

11、多表连接查询(内连接)

11.1 作用

单表数据不能满足查询需求时.
例子: 查询世界上小于100人的城市,所在的国家名,国土面积,城市名,人口数

引入:
第一张表city:
SELECT countrycode,NAME,population FROM city WHERE population<100;
#
city表得到,如下:
PCN
Adamstown
42

第二张表country:
DESC country; #
查看country表结构,得到下面有效的列与第一张表有关联。
CODE
NAME
SurfaceArea

SELECT NAME,SurfaceArea FROM country WHERE CODE=‘PCN‘;
#
country表得到,如下:
Pitcairn
49.00

11.2 多表连接基本语法

语法规则:

1.首先找涉及到的所有表

2.找到表和表之间的关联列

3.关联条件写在on后面

A join B on 关联列

4.所有需要查询的信息放在select

5.其他的过滤条件where group by having order by limit 往最后放

6.注意:对多表连接中,驱动表选择数据行少的表。后续所有表的关联列尽量是主键或唯一键(表设计),至少建立一个索引。

要求:

1、最核心的是,找到多张表之前的关联条件列

2、列书写时,必须是:表名.列

3、所有涉及到的查询列,都放在select后

4、将所有的过滤,分组,排序等条件按顺序写在on的后面

SELECT ???????????????????? ????????#查询 SELECT
country.name, ????????????????#
国家名 表名.
country.SurfaceArea, ????????????????#
国土面积 表名.
city.name, ????????????????#
城市名 表名.
city.Population ????????????????#
人口数 表名.
FROM city ????????????????#FROM
A
JOIN country ????????????????#JOIN
B
ON city.CountryCode = country.code ???? #ON
A.X = B.Y
WHERE city.population<100;

?

5、多张表

SELECT
XXX.XXX
XXX.XXX
FROM A #
A
JOIN B #
B
ON A.X = B.Y
JOIN C #
C
ON B.M = C.N

?

11.3 多表连接示例

案例准备:学生管理系统

use school
student
:学生表
===============
sno
:学号
sname
:学生姓名????
sage
:学生年龄
ssex
:学生性别

teacher
:教师表
===============
tno
:教师编号
tname
:教师名字

course
:课程表
===============
cno
:课程编号
cname
:课程名字
tno
:教师编号

score
:成绩表
===============
sno
:学号
cno
:课程编号
score
:成绩

--
项目构建
drop database school;
CREATE DATABASE school CHARSET utf8;
USE school

CREATE TABLE student(
sno INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT ‘
学号‘,
sname VARCHAR(20) NOT NULL COMMENT ‘
姓名‘,
sage TINYINT UNSIGNED NOT NULL COMMENT ‘
年龄‘,
ssex ENUM(‘f‘,‘m‘) NOT NULL DEFAULT ‘m‘ COMMENT ‘
性别
)ENGINE=INNODB CHARSET=utf8;

CREATE TABLE course(
cno INT NOT NULL PRIMARY KEY COMMENT ‘
课程编号‘,
cname VARCHAR(20) NOT NULL COMMENT ‘
课程名字‘,
tno INT NOT NULL COMMENT ‘
教师编号
)ENGINE=INNODB CHARSET utf8;

CREATE TABLE sc (
sno INT NOT NULL COMMENT ‘
学号‘,
cno INT NOT NULL COMMENT ‘
课程编号‘,
score INT NOT NULL DEFAULT 0 COMMENT ‘
成绩
)ENGINE=INNODB CHARSET=utf8;

CREATE TABLE teacher(
tno INT NOT NULL PRIMARY KEY COMMENT ‘
教师编号‘,
tname VARCHAR(20) NOT NULL COMMENT ‘
教师名字
)ENGINE=INNODB CHARSET utf8;

INSERT INTO student(sno,sname,sage,ssex)
VALUES (1,‘zhang3‘,18,‘m‘);

INSERT INTO student(sno,sname,sage,ssex)
VALUES
(2,‘zhang4‘,18,‘m‘),
(3,‘li4‘,18,‘m‘),
(4,‘wang5‘,19,‘f‘);

INSERT INTO student
VALUES
(5,‘zh4‘,18,‘m‘),
(6,‘zhao4‘,18,‘m‘),
(7,‘ma6‘,19,‘f‘);

INSERT INTO student(sname,sage,ssex)
VALUES
(‘oldboy‘,20,‘m‘),
(‘oldgirl‘,20,‘f‘),
(‘oldp‘,25,‘m‘);


INSERT INTO teacher(tno,tname) VALUES
(101,‘oldboy‘),
(102,‘hesw‘),
(103,‘oldguo‘);

DESC course;
INSERT INTO course(cno,cname,tno)
VALUES
(1001,‘linux‘,101),
(1002,‘python‘,102),
(1003,‘mysql‘,103);

DESC sc;
INSERT INTO sc(sno,cno,score)
VALUES
(1,1001,80),
(1,1002,59),
(2,1002,90),
(2,1003,100),
(3,1001,99),
(3,1003,40),
(4,1001,79),
(4,1002,61),
(4,1003,99),
(5,1003,40),
(6,1001,89),
(6,1003,77),
(7,1001,67),
(7,1003,82),
(8,1001,70),
(9,1003,80),
(10,1003,96);

SELECT * FROM student;
SELECT * FROM teacher;
SELECT * FROM course;
SELECT * FROM sc;

关联关系:

技术图片

11.4 多表SQL练习题

1.统计zhang3,学习了几门课

看题意:就两张表 即:student course课程表,但这两张表之间没有关联。需要通过score成绩表来进行关联。
所以:共需要三张表,: student score成绩表 course课程表。
几门课这个可以通过有几门成绩来判断有几门课。
最终确认:需要的是student score成绩表

SELECT student.sname,COUNT(sc.cno)
FROM student JOIN sc
ON student.sno=sc.sno
WHERE student.sname=‘zhang3‘
GROUP BY student.sno;

2.查询zhang3,学习的课程名称有哪些?

SELECT student.sname,course,cname
FROM student
JOIN sc
ON student.sno=sc.sno
JOIN course
ON sc.cno=course.cno
WHERE student.sname=‘zhang3‘; #
列显示结果

SELECT student.sname,GROUP_CONCAT(course,cname)
FROM student
JOIN sc
ON student.sno=sc.sno
JOIN course
ON sc.cno=course.cno
WHERE student.sname=‘zhang3‘
GROUP BY student.sname; #GROUP_CONCAT
列转行 行显示结果

3.查询oldguo老师教的学生名和个数.

SELECT teacher.tname,GROUP_CONCAT(student.sname),COUNT(student.sname)
FROM teacher
JOIN course
ON teacher.tno=course.tno
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
WHERE teacher.tname = ‘oldguo‘
GROUP BY teacher.tname;

4.查询oldguo所教课程的平均分数

SELECT teacher.tname,AVG(sc.score)
FROM teacher
JOIN course
on teacher.tno = course.tno
JOIN sc
ON course.cno = sc.cno
WHERE teacher.tname = ‘oldguo‘
GROUP by sc.cno;

5.每位老师所教课程的平均分,并按平均分排序

SELECT teacher.tname,course,cname,AVG(sc.score)
FROM teacher
JOIN course
ON teacher.tno = course.tno
JOIN sc
ON course.cno=sc.cno
GROUP BY teacher.tname,course,cname
ORDER BY AVG(sc.score);

6.查询oldguo所教的不及格的学生姓名

SELECT teacher.tname,student.sname,sc.score
FROM teacher
JOIN course
on teacher.tno = course.tno
JOIN sc
ON course.cno = sc.cno
JOIN student
ON sc.sno=student.sno
WHERE teacher.tname = ‘oldguo‘ AND sc.score<60;

7.查询所有老师所教学生不及格的信息

SELECT teacher.tname,group_CONCAT(student.sname,sc.score)
FROM teacher
JOIN course
on teacher.tno = course.tno
JOIN sc
ON course.cno = sc.cno
JOIN student
ON sc.sno=student.sno
GROUP BY teacher.tno
HAVING sc.score<60;

SELECT teacher.tname,group_CONCAT(CONCAT(student.sname,":",sc.score)) AS 不及格的
FROM teacher
JOIN course
on teacher.tno = course.tno
JOIN sc
ON course.cno = sc.cno
JOIN student
ON sc.sno=student.sno
WHERE sc.score<60
GROUP BY teacher.tno;

?

11.5 别名应用

1.别名语法

列别名,表别名
SELECT
a.Name AS an,
b.name AS bn,
b.SurfaceArea AS bs,
a.Population AS bp
FROM city AS a JOIN country AS b
ON a.CountryCode=b.Code
WHERE a.name =‘shenzheng‘;

注意说明:可以不带as.

2.表别名

SELECT t.tname,group_CONCAT(CONCAT(st.sname,":",sc.score))
FROM teacher as t
JOIN course as c
on t.tno = c.tno
JOIN sc
ON c.cno = sc.cno
JOIN student as st
ON sc.sno=st.sno
WHERE sc.score<60
GROUP BY t.tno;

注意说明:表别名是全局调用的.

3.列别名

SELECT t.tname as 讲师名 ,group_CONCAT(CONCAT(st.sname,":",sc.score)) as 不及格的
FROM teacher as t
JOIN course as c
on t.tno = c.tno
JOIN sc
ON c.cno = sc.cno
JOIN student as st
ON sc.sno=st.sno
WHERE sc.score<60
GROUP BY t.tno;

注意说明:列别名可以被 having order by 调用

4.查询一下世界上人口数量小于100人的城市名和国家名

SELECT b.name,a.name,a.population
FROM city AS a
JOIN country AS b
ON b.code=a.countrycode
WHERE a.Population<100

5.查询城市shenzhen,城市人口,所在国家名(name)及国土面积(SurfaceArea

SELECT a.name,a.population,b.name,b.SurfaceArea
FROM city AS a
JOIN country AS b
ON a.countrycode=b.code
WHERE a.name=‘shenzhen‘;

6.场景:有可能syxksyxk并不是同一个人,名字重名.

Name(名字)

Course(学科)

Count

syxk

linux

a,b,c,d

syxk

python

x,y,z

syxk

linux

10

hsw

python

11

12、扩展

12.1 视图的作用

技术图片

技术图片

12.2 元数据介绍及获取介绍

元数据是存储在"基表"中。

通过专用的DDL语句,DCL语句进行修改

通过专用视图和命令进行元数据的查询

information_schema中保存了大量元数据查询的视图

show 命令是封装好功能,提供元数据查询基础功能

13.3 information_schema的基本应用

tables 视图的应用

mysql> use information_schema;

mysql> desc tables;

常用的列举如下:

TABLE_SCHEMA 表所在的库名

TABLE_NAME???? 表名

ENGINE???????? 存储引擎

TABLE_ROWS???? 表的行数

AVG_ROW_LENGTH 表中行的平均行(字节)

INDEX_LENGTH 索引长度(索引的占用空间大小 字节)

示例:

USE information_schema;

DESC TABLES;

1. 显示所有的库和表的信息

SELECT table_schema,table_name FROM information_schema.tables;

2. 以以下模式显示所有的库和表的信息

world city,country,countrylanguage

SELECT table_schema,GROUP_CONCAT(table_name)

FROM information_schema.tables

GROUP BY table_schema; #将列转行显示,合并到一行。

3. 查询所有innodb引擎的表

SELECT table_schema,table_name,ENGINE

FROM information_schema.tables

WHERE ENGINE=‘innodb‘;

4. 统计world下的city表占用空间大小

表的数据量=平均行长度*行数 + 索引长度

AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH

SELECT table_name,(AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH)/1024

FROM information_schema.TABLES

WHERE table_schema=‘world‘ AND table_name=‘city‘;

5.统计world库数据量总大小

SELECT table_schema,SUM((AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH))/1024

FROM information_schema.TABLES

WHERE table_schema=‘world‘;

6.统计每个库的数据量大小,并按数据量从大到小排序

SELECT table_schema,SUM((AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH))/1024 AS total_KB

FROM information_schema.TABLES

GROUP BY table_schema

ORDER BY total_KB DESC;

7.配合concat()函数拼接语句或命令

示例:

1.模仿以下语句,进行数据库的分库分表备份。

mysqldump -uroot -p123 world city >/bak/world_city.sql #world 库名 city 表名

?

SELECT

CONCAT("mysqldump -uroot -p123",table_schema," ",table_name

," >/bak/",table_schema,"_",table_name,".sql")

FROM information_schema.tables;

2.模仿以下语句,进行批量生成对world库下所有表进行操作

ALTER TABLE world.city DISCARD TABLESPACE;

?

SELECT

CONCAT("ALTER TABLE ",table_schema,".",table_name," DISCARD TABLESPACE;")

FROM information_schema.tables

WHERE table_schema=‘world‘;

SQL基础应用

标签:多表连接   方式   where   alter   空值   lap   结构化   cat   需求   

原文地址:https://www.cnblogs.com/SyXk/p/12920595.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!