MySQL SQL的基础应用2

DQL应用

select

作用

获取MySQL中的数据行

单独使用select

select @@xxxx;获取参数信息。

mysql> select @@port;
mysql> show variables like '%innodb%';

select 函数();

mysql> select database();
mysql> select now();
mysql> select version();

SQL92标准的使用语法

select语法执行顺序(单表)

select开始 ---->
from子句 --->
where子句--->
group by子句--->
select后执行条件--->
having子句 ---->
order by ---->
limit

FROM

--- 例子:查询city表中的所有数据
USE world;
SELECT * FROM city;  --->适合表数据行较少,生产中使用较少。
SELECT * FROM world.city;
--- 例子: 查询name和population的所有值
SELECT NAME , population FROM city;
SELECT NAME , population FROM world.city;
单表查询练习环境:world数据库下表介绍
SHOW TABLES FROM world;
city(城市):
DESC city;
id: 自增的无关列,数据行的需要
NAME: 城市名字
countrycode:城市所在的国家代号,CHN,USA,JPN。。。。
district : 城市的所在的区域,中国是省的意思,美国是洲的意思
population: 城市的人口数量
说明: 此表是历史数据,仅供学习交流使用。

where

 WHERE
--- 例子:
--- WHERE 配合 等值查询(=)
--- 查询中国的城市信息
SELECT * 
FROM  world.city 
WHERE  countrycode='CHN';
--- 查询美国的城市信息
SELECT * 
FROM  world.city 
WHERE  countrycode='USA';
--- WHERE 配合 不等值(> < >= <=  <>)
--- 查询一下世界上人口小于100人的城市
SELECT * 
FROM  world.city 
WHERE population<100;
--- 查询世界上人口大于10000000的城市
略。
--- WHERE 配合 模糊(LIKE)
--- 查询国家代号是C开头的城市
SELECT * 
FROM  world.city 
WHERE countrycode
LIKE 'C%';
--- 注意:like 语句在MySQL中,不要出现%在前面的情况。因为效率很低,不走索引。
--- 错误的
SELECT * 
FROM  world.city 
WHERE countrycode
LIKE '%C%';
--- WHERE 配合 逻辑连接符(AND OR)
--- 查询城市人口在1w到2w之间的城市
SELECT *
FROM city
WHERE population >= 10000
AND Population <= 20000;
SELECT *
FROM city
WHERE population
BETWEEN 10000 AND 20000;
--- 查询一下中国或美国的城市信息
SELECT *
FROM city
WHERE countrycode='CHN' OR countrycode='USA';
SELECT *
FROM city
WHERE countrycode IN ('CHN','USA');
建议改写为,以下语句:
SELECT *
FROM city
WHERE countrycode='CHN'
UNION ALL
SELECT *
FROM city
WHERE countrycode='USA';

GROUP BY 配合聚合函数应用

常用聚合函数:
AVG()  ----平均值
COUNT() ----个数
SUM()  ----总和
MAX()  ----最大值
MIN()  ----最小值
GROUP_CONCAT()
--- 统计每个国家的总人口
SELECT  countrycode,SUM(population) FROM city GROUP BY countrycode ;
--- 统计每个国家的城市个数
1.拿什么站队
GROUP BY  countrycode
2. 拿什么统计
城市id,name
3. 统计的是什么?
COUNT(id)
SELECT countrycode,COUNT(id) FROM city GROUP BY countrycode;
--- 统计并显示 每个国家的省名字列表
SELECT countrycode,GROUP_CONCAT(district)  FROM city GROUP BY countrycode;
--- 统计中国每个省的城市名列表
SELECT  District,GROUP_CONCAT(NAME)
FROM city
WHERE countrycode='CHN'
GROUP BY district;
--- 统计一下中国,每个省的总人口数
SELECT  district ,SUM(population) FROM city
WHERE countrycode='CHN'
GROUP BY district
--- 统计一下中国,每个省的平均人口
SELECT  district ,AVG(population) FROM city
WHERE countrycode='CHN'
GROUP BY district

HAVING

--- 统计中国,每个省的总人口大于1000w的省及人口数
SELECT  district ,SUM(population) FROM city
WHERE countrycode='CHN'
GROUP BY district
HAVING  SUM(population)>10000000
说明: having后的条件是不走索引的,可以进行一些优化手段处理。

ORDER BY

SELECT  district ,SUM(population) FROM city
WHERE countrycode='CHN'
GROUP BY district
ORDER BY SUM(population) DESC  ;
--- 例子:查询中国所有的城市,并以人口数降序输出
SELECT * FROM city WHERE countrycode='CHN' ORDER BY  population DESC;

LIMIT

SELECT *
FROM city
WHERE countrycode='CHN'
ORDER BY  population DESC
LIMIT 5;
SELECT *
FROM city
WHERE countrycode='CHN'
ORDER BY  population DESC
LIMIT 10;
SELECT *
FROM city
WHERE countrycode='CHN'
ORDER BY  population DESC
LIMIT 5,3;
SELECT *
FROM city
WHERE countrycode='CHN'
ORDER BY  population DESC
LIMIT 3 OFFSET 5;
LIMIT M,N    跳过M行,显示N行
LIMIT X OFFSET Y 跳过Y行,显示X行

多表连接查询

什么时候用?

需要查询的数据是来自于多张表时。

怎么去多表连接查询

1.传统的连接:基于where条件
(1) 找表之间的关系列
(2) 排列查询条件
select name,countrycode from city whrere population<100;
PCN
select name,surfacearea from country where code='PCN'
--- 人口数量小于100人的城市,所在国家的国土面积(城市名,国家名,国土面积)
select city.name,country.name ,country.surfacearea
from city,country
where city.countrycode = country.code
and city.population<100
2. 内连接 *****
A  B
A.x  B.y
(1) 找表之间的关系列
(2) 将两表放在join左右
(3) 将关联条件了放在on后面
(4) 将所有的查询条件进行罗列
select A.m,B.n
from 
A  join  B
on A.x=B.y
where
group by
order by
limit
--- 例子:
--- 1. 查询人口数量小于100人的国家名,城市名,国土面积
SELECT country.name,city.name,country.surfacearea
FROM
city JOIN country
ON city.countrycode=country.code
WHERE city.population<100;
--- 2. 查询oldguo老师和他教课程名称
SELECT teacher.tname ,course.cname
FROM teacher
JOIN course
ON teacher.tno=course.tno
WHERE teacher.tname='oldguo';
SELECT teacher.`tname` ,course.`cname`
FROM teacher
JOIN course
ON teacher.`tno`=course.`tno`
WHERE teacher.`tname`='oldboy';
--- 3. 统计一下每门课程的总成绩
SELECT course.cname,SUM(sc.score)
FROM course 
JOIN sc
ON course.cno = sc.cno
GROUP BY course.cname;
-- 5.7 版本会报错的情况,在sqlyog中以下操作没问题
-- 但是在命令行上是会报错
SELECT course.cno,course.cname,SUM(sc.score)
FROM course 
JOIN sc
ON course.cno = sc.cno
GROUP BY course.cname;
mysql> SELECT course.cno,course.cname,SUM(sc.score)                                                                   
    -> FROM course 
    -> JOIN sc
    -> ON course.cno = sc.cno
    -> GROUP BY course.cname;
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'school.course.cno' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
1. 在select后面出现的列,不是分组条件,并且没有在函数中出现。
2. 如果group by 后是主键列或者是唯一条件列,不会报出错误。如下:
SELECT
course.cno,course.cname,SUM(sc.score)                                                                    FROM course 
JOIN sc
ON course.cno = sc.cno
GROUP BY course.cno;
3. 外链接 ****
--- 4. 查询oldguo老师教的学生姓名列表
SELECT teacher.tname,GROUP_CONCAT(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;
--- 5. 查询所有老师教的学生姓名列表
SELECT teacher.tname,GROUP_CONCAT(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
GROUP BY teacher.tno;
--- 6. 查询oldboy老师教的不及格学生的姓名
SELECT teacher.tname,GROUP_CONCAT(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='oldboy' AND sc.score<60
GROUP BY teacher.tno;
--- 7. 统计zhang3,学习了几门课
SELECT student.`sname` ,COUNT(sc.`cno`)
FROM student
JOIN sc
ON student.`sno`=sc.`sno`
WHERE student.sname='zhang3';
--- 8. 查询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';
--- 9. 查询oldguo老师教的学生名.
SELECT teacher.tname,GROUP_CONCAT(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;
--- 10.查询oldguo所教课程的平均分数
SELECT teacher.tname ,course.`cname`,AVG(sc.`score`)
FROM teacher
JOIN course
ON teacher.`tno`=course.`tno`
JOIN sc
ON course.`cno`=sc.`cno`
WHERE teacher.tname='oldguo';
--- 11.每位老师所教课程的平均分,并按平均分排序
SELECT teacher.tname ,course.`cname`,AVG(sc.`score`)
FROM teacher
JOIN course
ON teacher.`tno`=course.`tno`
JOIN sc
ON course.`cno`=sc.`cno`
ORDER BY AVG(sc.`score`);
--- 12.查询oldguo所教的不及格的学生姓名
SELECT teacher.tname,GROUP_CONCAT(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' AND sc.score<60
GROUP BY teacher.tno;
--- 13.查询所有老师所教学生不及格的信息
SELECT teacher.tname,GROUP_CONCAT(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 sc.score<60;

上述案例表结构

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;

show

show databases;                                   #查看所有数据库
show tables;                                          #查看当前库的所有表
SHOW TABLES FROM                        #查看某个指定库下的表
show create database world                #查看建库语句
show create table world.city                #查看建表语句
show  grants for  root@'localhost'      #查看用户的权限信息
show  charset;                                  #查看字符集
show collation                                      #查看校对规则
show processlist;                                  #查看数据库连接情况
show index from                                #表的索引情况
show status                                        #数据库状态查看
SHOW STATUS LIKE '%lock%';        #模糊查询数据库某些状态
SHOW VARIABLES                            #查看所有配置信息
SHOW variables LIKE '%lock%';          #查看部分配置信息
show engines                                      #查看支持的所有的存储引擎
show engine innodb status\G              #查看InnoDB引擎相关的状态信息
show binary logs                                    #列举所有的二进制日志
show master status                                #查看数据库的日志位置信息
show binlog evnets in                            #查看二进制日志事件
show slave status \G                            #查看从库状态
SHOW RELAYLOG EVENTS              #查看从库relaylog事件信息
desc  (show colums from city)              #查看表的列定义信息

Information_schema

DESC information_schema.TABLES
TABLE_SCHEMA        ---->库名
TABLE_NAME             ---->表名
ENGINE                        ---->引擎
TABLE_ROWS              ---->表的行数
AVG_ROW_LENGTH   ---->表中行的平均行(字节)
INDEX_LENGTH            ---->索引的占用空间大小(字节)

查询整个数据库中所有库和所对应的表信息

SELECT table_schema,GROUP_CONCAT(table_name)
FROM  information_schema.tables
GROUP BY table_schema;

统计所有库下的表个数

SELECT table_schema,COUNT(table_name)
FROM information_schema.TABLES
GROUP BY table_schema

查询所有innodb引擎的表及所在的库

SELECT table_schema,table_name,ENGINE FROM information_schema.`TABLES`
WHERE ENGINE='innodb';

统计world数据库下每张表的磁盘空间占用

SELECT table_name,CONCAT((TABLE_ROWS*AVG_ROW_LENGTH+INDEX_LENGTH)/1024," KB")  AS size_KB
FROM information_schema.tables WHERE TABLE_SCHEMA='world';

统计所有数据库的总的磁盘空间占用

SELECT
TABLE_SCHEMA,
CONCAT(SUM(TABLE_ROWS*AVG_ROW_LENGTH+INDEX_LENGTH)/1024," KB") AS Total_KB
FROM information_schema.tables
GROUP BY table_schema;
mysql -uroot -p123 -e "SELECT TABLE_SCHEMA,CONCAT(SUM(TABLE_ROWS*AVG_ROW_LENGTH+INDEX_LENGTH)/1024,' KB') AS Total_KB FROM information_schema.tables GROUP BY table_schema;"

生成整个数据库下的所有表的单独备份语句

模板语句:
mysqldump -uroot -p123 world city >/tmp/world_city.sql
SELECT CONCAT("mysqldump -uroot -p123 ",table_schema," ",table_name," >/tmp/",table_schema,"_",table_name,".sql" )
FROM information_schema.tables
WHERE table_schema NOT IN('information_schema','performance_schema','sys')
INTO OUTFILE '/tmp/bak.sh' ;
CONCAT("mysqldump -uroot -p123 ",table_schema," ",table_name," >/tmp/",table_schema,"_",table_name,".sql" )

107张表,都需要执行以下2条语句

ALTER TABLE world.city DISCARD TABLESPACE;
ALTER TABLE world.city IMPORT TABLESPACE;
SELECT CONCAT("alter table ",table_schema,".",table_name," discard tablespace")
FROM information_schema.tables
WHERE table_schema='world'
INTO OUTFILE '/tmp/dis.sql';

熟悉业务:

刚入职时,DBA的任务

1. 搞清楚架构
通过公司架构图,搞清楚数据库的物理架构
1-2天
逻辑结构:
(1)生产库的信息(容易达到)
(2)库下表的信息(非常复杂)
    1. 开发和业务人员,搞好关系
    2. 搞到ER图(PD)
    3. 啥都没有怎么怎么办?
       (1) 找到建表语句,如果有注释,读懂注释。如果没有注释,只能根据列名翻译
       (2) 找到表中部分数据 ,分析数据特点,达到了解列功能的目录

你可能感兴趣的:(MySQL SQL的基础应用2)