MYSQL(入门,全是重点)

借鉴于:http://xuesql.cn/ 

1,SELECT查询

        SELECT 语句, 称为查询语句 

        SELECT column(列名), another_column, … FROM mytable(表名);

如下表 Movies :

IdTitleDirectorYearLength_minutes
1Toy StoryJohn Lasseter199581
2A Bug's LifeJohn Lasseter199895
3Toy Story 2John Lasseter199993
4Monsters, Inc.Pete Docter200192
5Finding NemoFinding Nemo2003107
6The IncrediblesBrad Bird2004116
7CarsJohn Lasseter2006117
8RatatouilleBrad Bird2007115
9WALL-EAndrew Stanton2008104
10UpPete Docter2009101
11Toy Story 3Lee Unkrich2010103
12Cars 2John Lasseter2011120
13BraveBrenda Chapman2012102
14Monsters UniversityDan Scanlon2013110

我们需要查询所有:

SELECT * FROM movies;
  1. 【简单查询】找到所有电影的名称title
  2. 【简单查询】找到所有电影的导演
  3. 【简单查询】找到所有电影的名称和导演
  4. 【简单查询】找到所有电影的名称和上映年份
  5. 【简单查询】找到所有电影的所有信息
  6. 【简单查询】找到所有电影的名称,Id和播放时长
SELECT title FROM movies;
SELECT Director FROM movies;
SELECT title,Director FROM movies;
SELECT title,year FROM movies;
SELECT *  FROM movies;
SELECT title,id,Length_minutes FROM movies;

2,查询条件

        平常我们的查询需要就是需要条件来进行查询,需要使用的就是where

        SELECT (列) FROM WHERE (条件);

  1. 【简单条件】找到id为6的电影 
  2. 【简单条件】找到在2000-2010年间year上映的电影 
  3. 【简单条件】找到不是在2000-2010年间year上映的电影 
  4. 【简单条件】找到头5部电影 
  5. 【简单条件】找到2010(含)年之后的电影里片长小于两个小时的片子 
SELECT * FROM movies;
SELECT * FROM movies where id=6;
SELECT * FROM movies where year<=2010 and year>=2000;
SELECT * FROM movies where year>2010 or year<2000;
SELECT * FROM movies where id<6;
SELECT * FROM movies where year>=2010 and Length_minutes<120;

        增加查询条件,比如模糊查询,就要使用到like,需要使用到%通配符:

  1. 【复杂条件】找到所有Toy Story系列电影 
  2. 【复杂条件】找到所有John Lasseter导演的电影 
  3. 【复杂条件】找到所有不是John Lasseter导演的电影 
  4. 【复杂条件】找到所有电影名为 "WALL-" 开头的电影 
  5. 【复杂条件】有一部98年电影中文名《虫虫危机》请给我找出来 
SELECT * FROM movies;
SELECT * FROM movies where title like "%Toy Story%";
SELECT * FROM movies where Director="John Lasseter";
SELECT * FROM movies where Director!="John Lasseter";
SELECT * FROM movies where Title like "WALL%";
SELECT * FROM movies where year like "%98";

3,查询结果过滤和排序

        DISTINCT语法,使用这个gaugau关键字来指定某个(多个)属性列唯一返回.

        SELECT DISTINCT (属性列名) FROM (表) WHERE (条件);

        因为 DISTINCT 语法会直接删除重复的行, 我们还会学习 GROUP BY 语句.

        然后就是对查询的结果按照要求进行排序:

        可以使用ORDER BY (属性列名)排序的语法来让结果按照一个或者多个属性做排序.正序:ASD,倒序:DESC

        然后通过LIMIIT选取部分结果:

SELECT DISTINCT (属性列名) 
FROM (表) 
WHERE (条件)
ORDER BY column ASC/DESC
LIMIT (个数) OFFSET (开始位置);
  1. 【结果排序】按导演名排重列出所有电影(只显示导演),并按导演名正序排列
SELECT distinct Director 
FROM movies
order by director;
  1. 【结果排序】列出按上映年份最新上线的4部电影
SELECT distinct * 
FROM movies
order by year desc
limit 4;
  1. 【结果排序】按电影名字母序升序排列,列出前5部电影
SELECT distinct * 
FROM movies
order by Title 
limit 5;
  1. 【结果排序】按电影名字母序升序排列,列出上一题之后的5部电影
SELECT distinct * 
FROM movies
order by Title
limit 5 OFFSET 5;
  1. 【结果排序】如果按片长排列,John Lasseter导演导过片长第3长的电影是哪部,列出名字即可
SELECT distinct Title 
FROM movies
order by Length_minutes
limit 1 OFFSET 3;

4,多表联合查询

        使用JSINS进行多表联合查询

        主键:一般关系数据库中,都会有一个属性设置为主键,借助主键,我们可以把两个表中具有相同主键ID的数据连接起来,使用到JOIN关键字.

SELECT (属性列名)
FROM (主表)
INNER JOIN(要连接的表)
    ON mytable.id = another_table.id (主键连接,两个相同的连成1条)
WHERE (条件)
ORDER BY column, … ASC/DESC
LIMIT (个数)OFFSET (开始位置);

例题:

Table:Movies 

IdTitleDirectorYearLength_minutes
1Toy StoryJohn Lasseter199581
2A Bug's LifeJohn Lasseter199895
3Toy Story 2John Lasseter199993
4Monsters, Inc.Pete Docter200192
5Finding NemoFinding Nemo2003107
6The IncrediblesBrad Bird2004116
7CarsJohn Lasseter2006117
8RatatouilleBrad Bird2007115
9WALL-EAndrew Stanton2008104
10UpPete Docter2009101
11Toy Story 3Lee Unkrich2010103
12Cars 2John Lasseter2011120
13BraveBrenda Chapman2012102
14Monsters UniversityDan Scanlon2013110

Boxoffice :

Movie_idRatingDomestic_salesInternational_sales
58.2380843261555900000
147.4268492764475066843
88206445654417277164
126.4191452396368400000
37.9245852179239163000
68261441092370001000
98.5223808164297503696
118.4415004880648167031
18.3191796233170162503
77.2244082982217900167
108.3293004164438338580
48.1289916256272900000
27.2162798565200600000
137.2237283207301700000
  1. 【联表】找到所有电影的国内Domestic_sales和国际销售额
SELECT *
FROM movies
inner join Boxoffice 
	on Movies.id=Boxoffice.Movie_id;
  1. 【联表】找到所有国际销售额比国内销售大的电影
SELECT *
FROM movies
inner join Boxoffice 
	on Movies.id=Boxoffice.Movie_id
where International_sales>Domestic_sales;
  1. 【联表】找出所有电影按市场占有率rating倒序排列
SELECT *
FROM movies
inner join Boxoffice 
	on Movies.id=Boxoffice.Movie_id
order by rating desc;
  1. 【联表】每部电影按国际销售额比较,排名最靠前的导演是谁,国际销量多少
SELECT Director,International_sales
FROM movies
inner join Boxoffice 
	on Movies.id=Boxoffice.Movie_id
order by  International_sales desc
limit 1;

5,外连接

   INNER JOIN 只会保留两个表都存在的数据,意味着一些数据的丢失.

        于是我们就要介绍左连接LEFT JOIN,右连接RIGHT JOIN 和 全连接FULL JOIN.

SELECT (属性列名)
FROM (主表)
INNER/LEFT/RIGHT/FULL JOIN (需要连接的表)
    ON mytable.id = another_table.matching_id
WHERE (条件)
ORDER BY (排序的条件), … ASC/DESC
LIMIT (个数) OFFSET (位置);

        例子:

Employees :

RoleNameBuildingYears_employed
EngineerBecky A.1e4
EngineerDan B.1e2
EngineerSharon F.1e6
EngineerDan M.1e4
EngineerMalcom S.1e1
ArtistTylar S.2w2
ArtistSherman D.2w8
ArtistJakob J.2w6
ArtistLillia A.2w7
ArtistBrandon J.2w7
ManagerScott K.1e9
ManagerShirlee M.1e3
ManagerDaria O.2w6
EngineerYancy I.null0
ArtistOliver P.null0

 Buildings :

Building_nameCapacity
1e24
1w32
2e16
2w20
  1. 【复习】找到所有有雇员的办公室(buildings)名字
SELECT distinct Building_name
FROM Employees   
left join Buildings   
	on Employees.Building=Buildings .Building_name
where Building_name is not null;
  1. 【复习】找到所有办公室里的所有角色(包含没有雇员的),并做唯一输出(DISTINCT)
SELECT  distinct role,Building_name
FROM Buildings   
left join Employees   
	on Employees.Building=Buildings .Building_name
  1. 【难题】找到所有有雇员的办公室(buildings)和对应的容量
SELECT  distinct Building_name,Capacity
FROM Buildings   
left join Employees   
	on Employees.Building=Buildings .Building_name
where building

6,NULL关键字

        null还是无的意思,因为我们可能要考虑到某个属性为null 的情况,这种特殊性质会导致编写SQL的复杂性,尽量减少null的使用.

        如果多表连接,A和B有数据差异, 必须要null来填充,可以用is 努力了或者是 is not null 来选这个字段是否等于null.

        还是根据5中的员工两个表,举例子:

  1. 【复习】找到雇员里还没有分配办公室的(列出名字和角色就可以)
SELECT name,role
from Employees 
left join Buildings
	on Employees.Building=Buildings .Building_name
where building is null;
  1. 【难题】找到还没有雇员的办公室
SELECT building_name
from Buildings 
left join Employees
	on Employees.Building=Buildings .Building_name
where building is null;

7,在查询中使用表达式

        顾名思义,就是对数字或者字符串的运算

SELECT  particle_speed / 2.0 AS half_particle_speed (对结果做了一个除2)
FROM physics_data
WHERE ABS(particle_position) * 10.0 >500
            (条件要求这个属性绝对值乘以10大于500);

        AS就是取别名

例子:

Movies :

IdTitleDirectorYearLength_minutes
1Toy StoryJohn Lasseter199581
2A Bug's LifeJohn Lasseter199895
3Toy Story 2John Lasseter199993
4Monsters, Inc.Pete Docter200192
5Finding NemoFinding Nemo2003107
6The IncrediblesBrad Bird2004116
7CarsJohn Lasseter2006117
8RatatouilleBrad Bird2007115
9WALL-EAndrew Stanton2008104
10UpPete Docter2009101
11Toy Story 3Lee Unkrich2010103
12Cars 2John Lasseter2011120
13BraveBrenda Chapman2012102
14Monsters UniversityDan Scanlon2013110

 Boxoffice :

Movie_idRatingDomestic_salesInternational_sales
58.2380843261555900000
147.4268492764475066843
88206445654417277164
126.4191452396368400000
37.9245852179239163000
68261441092370001000
98.5223808164297503696
118.4415004880648167031
18.3191796233170162503
77.2244082982217900167
108.3293004164438338580
48.1289916256272900000
27.2162798565200600000
137.2237283207301700000

         

  1. 【计算】列出所有的电影ID,名字和销售总额(以百万美元为单位计算) 
SELECT id,title, (b.Domestic_sales+b.International_sales)/1000000 AS sales
FROM movies m
left join Boxoffice b
on m.id=b.Movie_id
  1. 【计算】列出所有的电影ID,名字和市场指数(Rating的10倍为市场指数)
SELECT id,title, b.Rating*10 AS sales
FROM movies m
left join Boxoffice b
on m.id=b.Movie_id
  1. 【计算】列出所有偶数年份的电影,需要电影ID,名字和年份
SELECT Id,Title,Year
FROM Movies
WHERE Year%2=0
  1. 【难题】John Lasseter导演的每部电影每分钟值多少钱,告诉我最高的3个电影名和价值就可以
SELECT title, (b.Domestic_sales+b.International_sales)/m.length_minutes AS sales
FROM movies m
left join Boxoffice b
on m.id=b.Movie_id
where Director="John Lasseter"
order by sales desc
limit 3

8,在查询中统计

        对数据进行计数,求平均值等操作.

SELECT AGG_FUNC(column_or_expression) AS aggregate_description, …
FROM mytable
WHERE constraint_expression;

常用函数:

  • count:计数----count(*)统计数据的行数,count(colnmn)统计column非null的行数
  • min(column):找column最小的一行,与之相反就是max
  • AUG(column):找column所有行取平均值
  • SUM(column):对column所有行求和

        其次,group by 可以对某个数据进行分组,可以组合,对分组进行统计.

SELECT 属性列名,count(*)
FROM 主表
where 条件 group by 属性名;

例子:

Employees :

RoleNameBuildingYears_employed
EngineerBecky A.1e4
EngineerDan B.1e2
EngineerSharon F.1e6
EngineerDan M.1e4
EngineerMalcom S.1e1
ArtistTylar S.2w2
ArtistSherman D.2w8
ArtistJakob J.2w6
ArtistLillia A.2w7
ArtistBrandon J.2w7
ManagerScott K.1e9
ManagerShirlee M.1e3
ManagerDaria O.2w6
EngineerYancy I.null0
ArtistOliver P.null0
  1. 【统计】找出就职年份最高的雇员(列出雇员名字+年份)
SELECT name,MAX(Years_employed)
FROM employees;
  1. 【分组】按角色(Role)统计一下每个角色的平均就职年份
SELECT Role,AVG(Years_employed)
FROM Employees GROUP by Role;
  1. 【分组】按办公室名字总计一下就职年份总和
SELECT Building,sum(Years_employed)
FROM Employees group by Building;
  1. 【难题】每栋办公室按人数排名,不要统计无办公室的雇员
SELECT Building,count(*)
FROM Employees  
where building is not null group by Building;

        在group语法之中,我们知道数据库是对数据先做where操作,然后分组统计,但是我们如果要分组完再筛选出数据,就要使用having语法(HAVING 和 WHERE 语法一样,只不过作用的结果集不一样. )

SELECT group_by_column, AGG_FUNC(column_expression) AS aggregate_result_alias, …
FROM mytable
WHERE condition
GROUP BY column
HAVING group_condition;

        例子:

  1. 【统计】统计一下Artist角色的雇员数量
SELECT COUNT() FROM Employees WHERE Role='Artist';
  1. 【分组】按角色统计一下每个角色的雇员数量
SELECT COUNT(*),role
FROM Employees 
group by role;
  1. 【分组】算出Engineer角色的就职年份总计
SELECT SUM(Years_employed)
FROM Employees 
where Role="Engineer";
  1. 【难题】按角色分组算出每个角色按有办公室和没办公室的统计人数(列出角色,数量,有无办公室,注意一个角色如果部分有办公室,部分没有需分开统计)
SELECT Role,CASE when Building is NOT NULL 
THEN '1' ELSE '0' END
AS Have,COUNT(Name)
FROM Employees
GROUP BY Role,Have;

 由此可见having用的真的少(这些例题都没用上)

9,查询执行顺序

        介绍了所有查询的相关语法,大概梳理一下所有语法的执行顺序:

  1. from和join
  2. where
  3. group by
  4. having 
  5. select
  6. distinct
  7. order by
  8. limit/offset

        不是每一个SQL语句都要用到所有的句法,但灵活运用以上的句法组合和深刻理解SQL执行原理将能在SQL层面更好的解决数据问题,而不用把问题都抛给程序逻辑.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会Java的MING

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值