《MySQL基础教程》笔记7

Web  2023年12月2日 am8:08发布11个月前更新 91es.com站长
88 0 0

前言

主要是记录一下join和where等命令的使用。根据《MySQL基础教程-西泽梦路》学习,简单的做一下笔记。

记录于此,方便自己回忆。

正文

我这以Window版的phpstudy软件验证。

需要进入这个目录,才可以使用mysql命令

D:\phpstudy_pro\Extensions\MySQL5.7.26\bin

进入正文

创建tb1和tb2

create table tb1 (empid varchar(30), name varchar(30), age int);
create table tb2 (empid varchar(30), name varchar(30), age int);
# tb1
mysql> select * from tb1;
+-------+--------+------+
| empid | name   | age  |
+-------+--------+------+
| A101  | 佐藤   |   40 |
| A102  | 高桥   |   28 |
| A103  | 中川   |   20 |
| A104  | 渡边   |   23 |
| A105  | 西泽   |   35 |
+-------+--------+------+
# tb2
mysql> select * from tb2;
+-------+--------+------+
| empid | name   | age  |
+-------+--------+------+
| A106  | 中天   |   26 |
| A107  | 铃木   |   24 |
| A108  | 村警   |   25 |
| A110  | 几天   |   27 |
| A109  | 田中   |   23 |
+-------+--------+------+

tb3

create table tb3 (empid varchar(30),sales int,month int);
# tb3
mysql> select * from tb3;
+-------+-------+-------+
| empid | sales | month |
+-------+-------+-------+
| A103  |   101 |     4 |
| A102  |    54 |     5 |
| A104  |   181 |     4 |
| A101  |   184 |     4 |
| A103  |    17 |     5 |
| A101  |   300 |     5 |
| A102  |   205 |     6 |
| A104  |    93 |     5 |
| A103  |    12 |     6 |
| A107  |    87 |     6 |
+-------+-------+-------+

进入正题。

union

使用union可以组合两个表。

PS: 就是多个select命令的组合

select 列名1 from 表名1 union select 列表2 from 表名2;

通过union,会把表名1和表名2根据条件进行组合。

mysql> select * from tb1 union select * from tb2;
+-------+--------+------+
| empid | name   | age  |
+-------+--------+------+
| A101  | 佐藤   |   40 |
| A102  | 高桥   |   28 |
| A103  | 中川   |   20 |
| A104  | 渡边   |   23 |
| A105  | 西泽   |   35 |
| A106  | 中天   |   26 |
| A107  | 铃木   |   24 |
| A108  | 村警   |   25 |
| A110  | 几天   |   27 |
| A109  | 田中   |   23 |
+-------+--------+------+

当然,上面的只是组合后临时展示的,如果要放入新的表中,可以用下面命令:

# 把组合的tb1和tb2放入创建的tb3中
create table tb3 select * from tb1 union select * from tb2;

加入tb1和tb2中有重复数据?

# 给tb2创建一条跟tb1一样的数据
insert into tb2 (empid,name,age) values("A101","佐藤",40);

然后通过union组合发现,默认情况组合后的数据不会有多条"A101",因为union默认会[消除重复记录]。

如果要允许重复,就需要使用 union all,组合所有的。

mysql> select * from tb1 union all select * from tb2;
+-------+--------+------+
| empid | name   | age  |
+-------+--------+------+
| A101  | 佐藤   |   40 |
| A102  | 高桥   |   28 |
| A103  | 中川   |   20 |
| A104  | 渡边   |   23 |
| A105  | 西泽   |   35 |
| A106  | 中天   |   26 |
| A107  | 铃木   |   24 |
| A108  | 村警   |   25 |
| A110  | 几天   |   27 |
| A109  | 田中   |   23 |
| A101  | 佐藤   |   40 |
+-------+--------+------+

JOIN

使用JOIN连接两个表。

select 查询列名 from 表名1 join 表名2 on 表名1.列名=表名2.列名;

我们以tb1和tb3连接。

mysql> select * from tb1 join tb3 on tb1.empid=tb3.empid;
+-------+--------+------+-------+-------+-------+
| empid | name   | age  | empid | sales | month |
+-------+--------+------+-------+-------+-------+
| A103  | 中川   |   20 | A103  |   101 |     4 |
| A102  | 高桥   |   28 | A102  |    54 |     5 |
| A104  | 渡边   |   23 | A104  |   181 |     4 |
| A101  | 佐藤   |   40 | A101  |   184 |     4 |
| A103  | 中川   |   20 | A103  |    17 |     5 |
| A101  | 佐藤   |   40 | A101  |   300 |     5 |
| A102  | 高桥   |   28 | A102  |   205 |     6 |
| A104  | 渡边   |   23 | A104  |    93 |     5 |
| A103  | 中川   |   20 | A103  |    12 |     6 |
+-------+--------+------+-------+-------+-------+
9 rows in set (0.00 sec)
内连接

像这样把不同的表中相匹配的记录提取出来的连接方式称为内连接。

如果要明确指出某一处理是内连接,可以将join部分写成inner join

join 默认是内连接,也就是可以不写inner

mysql> select * from tb1 inner join tb3 on tb1.empid=tb3.empid;
+-------+--------+------+-------+-------+-------+
| empid | name   | age  | empid | sales | month |
+-------+--------+------+-------+-------+-------+
| A103  | 中川   |   20 | A103  |   101 |     4 |
| A102  | 高桥   |   28 | A102  |    54 |     5 |
| A104  | 渡边   |   23 | A104  |   181 |     4 |
| A101  | 佐藤   |   40 | A101  |   184 |     4 |
| A103  | 中川   |   20 | A103  |    17 |     5 |
| A101  | 佐藤   |   40 | A101  |   300 |     5 |
| A102  | 高桥   |   28 | A102  |   205 |     6 |
| A104  | 渡边   |   23 | A104  |    93 |     5 |
| A103  | 中川   |   20 | A103  |    12 |     6 |
+-------+--------+------+-------+-------+-------+
选择列进行显示

上面是*显示所有的列(也就是表1和表2中组合的)。

假如只需要显示指定的呢?比如表1中的列和表2中的列?

mysql> select tb1.empid,tb1.name,tb3.sales from tb1 join tb3 on tb1.empid=tb3.empid;
+-------+--------+-------+
| empid | name   | sales |
+-------+--------+-------+
| A103  | 中川   |   101 |
| A102  | 高桥   |    54 |
| A104  | 渡边   |   181 |
| A101  | 佐藤   |   184 |
| A103  | 中川   |    17 |
| A101  | 佐藤   |   300 |
| A102  | 高桥   |   205 |
| A104  | 渡边   |    93 |
| A103  | 中川   |    12 |
+-------+--------+-------+
给表添加别名的方法

之前学习过,添加别名是用as

# table1是tb1的别名,当然,这种别名执行完就消失了,并没有啥作用。
select * from tb1 as table1;

但在join连接中就可以作用。

mysql> select table_x.empid,table_x.name,table_y.sales from tb1 as table_x join tb3 as table_y on table_x.empid=table_y.empid;
+-------+--------+-------+
| empid | name   | sales |
+-------+--------+-------+
| A103  | 中川   |   101 |
| A102  | 高桥   |    54 |
| A104  | 渡边   |   181 |
| A101  | 佐藤   |   184 |
| A103  | 中川   |    17 |
| A101  | 佐藤   |   300 |
| A102  | 高桥   |   205 |
| A104  | 渡边   |    93 |
| A103  | 中川   |    12 |
+-------+--------+-------+
9 rows in set (0.00 sec)

效果跟上面不使用别名一样。

using

上面join on

select 查询列名 from 表名1 join 表名2 on 表名1.列名=表名2.列名;

中用了[表名1.列名=表名2.列名]进行比较。而且上面例子中

select * from tb1 join tb3 on tb1.empid=tb3.empid;

比较的列名都是empid。

这种相同列名情况下,可以使用using(相同的列名)替换。

select 显示的列名 from 表1 join 表2 using(empid);

这种是相同列名下才可以使用。

来个例子

mysql> select tb1.empid,tb1.name,tb3.sales from tb1 join tb3 using(empid);
+-------+--------+-------+
| empid | name   | sales |
+-------+--------+-------+
| A103  | 中川   |   101 |
| A102  | 高桥   |    54 |
| A104  | 渡边   |   181 |
| A101  | 佐藤   |   184 |
| A103  | 中川   |    17 |
| A101  | 佐藤   |   300 |
| A102  | 高桥   |   205 |
| A104  | 渡边   |    93 |
| A103  | 中川   |    12 |
+-------+--------+-------+
通过WHERE设置条件从连接表中提取记录

join on或join using() 后还可以跟where设置条件。

mysql> select tb1.empid,tb1.name,tb3.sales from tb1 join tb3 using(empid) where tb3.sales>=100;
+-------+--------+-------+
| empid | name   | sales |
+-------+--------+-------+
| A101  | 佐藤   |   184 |
| A101  | 佐藤   |   300 |
| A102  | 高桥   |   205 |
| A103  | 中川   |   101 |
| A104  | 渡边   |   181 |
+-------+--------+-------+
5 rows in set (0.00 sec)

更复杂的这里不介绍了,具体请看书吧。

外连接

上面介绍的就是内连接,只会提取与连接键相同匹配的记录。

细心的你会发现,之前拼接的表中少了部分员工

外连接就是所有的记录,包括与连接键不相同的记录。

外连接氛围左外连接(left join)和右外连接(right join)。

内连接 : join 或inner join

左外连接 : left join

右外连接 : right join

# 左外连接
mysql> select tb1.empid,tb1.name,tb3.sales from tb1 left join tb3 on tb1.empid=tb3.empid;
+-------+--------+-------+
| empid | name   | sales |
+-------+--------+-------+
| A103  | 中川   |   101 |
| A102  | 高桥   |    54 |
| A104  | 渡边   |   181 |
| A101  | 佐藤   |   184 |
| A103  | 中川   |    17 |
| A101  | 佐藤   |   300 |
| A102  | 高桥   |   205 |
| A104  | 渡边   |    93 |
| A103  | 中川   |    12 |
| A105  | 西泽   |  NULL |
+-------+--------+-------+
10 rows in set (0.00 sec)
# 右外连接
mysql> select tb1.empid,tb1.name,tb3.sales from tb1 right join tb3 on tb1.empid=tb3.empid;
+-------+--------+-------+
| empid | name   | sales |
+-------+--------+-------+
| A101  | 佐藤   |   184 |
| A101  | 佐藤   |   300 |
| A102  | 高桥   |    54 |
| A102  | 高桥   |   205 |
| A103  | 中川   |   101 |
| A103  | 中川   |    17 |
| A103  | 中川   |    12 |
| A104  | 渡边   |   181 |
| A104  | 渡边   |    93 |
| NULL  | NULL   |    87 |
+-------+--------+-------+
10 rows in set (0.00 sec)

发现还有其他的连接啥的,这里暂时不深究哈。

where in(select)
select 查询的列 from 表名 where 列名 in (通过只查询select语句提取的列);
max

查询表tb3中列sales最大值的记录?

这个如何查询呢?

# 错误写法
# 只写MAX(sales)是不会计算出列sales的最大值的!
mysql> select * from tb3 where sales=max(sales);
ERROR 1111 (HY000): Invalid use of group function

看是合理,其实却显示异常。

查询最大的sales值的

mysql> select max(sales) from tb3;
+------------+
| max(sales) |
+------------
|        300 |
+------------+
1 row in set (0.06 sec)

如果要查询最大sales的记录信息,就需要使用where in进行组合

mysql> select * from tb3 where sales in (select max(sales) from tb3);
+-------+-------+-------+
| empid | sales | month |
+-------+-------+-------+
| A101  |   300 |     5 |
+-------+-------+-------+
1 row in set (0.00 sec)
avg

查询tb1中age大于等于平均年龄的记录

mysql> select * from tb1 where age >= (select avg(age) from tb1);
+-------+--------+------+
| empid | name   | age  |
+-------+--------+------+
| A101  | 佐藤   |   40 |
| A105  | 西泽   |   35 |
+-------+--------+------+

参考文章

  1. 《MySQL基础教程-西泽梦路》

 历史上的今天

  1. 2019: 陈忠实:马罗大叔(0条评论)
  2. 2018: linux禁止root远程登录(0条评论)
  3. 2018: 替换preg_replace(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

[摘]Handler内存泄露原理及解决方法

SHUI知道本想总结,也懒了,看网上也有很多人总结,也就摘抄于此,以供自己查阅。前言因为Android采取了单线程UI模型,开发者无法在子线程中更新UI,为此Android为我们提供了Handler这个工具,可以开发者切换到主线程更新UI。示例首先看一段示例代码public class...

linux chmod和chown的使用

本文参考《linux chmod命令和chown命令》,在此感谢作者的贡献。使用命令有时候想不起来,因此摘抄于此,以作为记录。1、文件权限的查询如果有文件夹/home/water/myshell.sh以下命令查询文件或文件夹的所有属性ls -l /home 查询的是home目录下所有文件...

Kotlin空值处理简介

前言简单记录一下Kotlin中变量的空值处理的方式。记录于此方便自己查阅。正文Kotlin把变量分成两种类型,一种是可空类型的变量,一种是非空类型的变量。一般情况下,一个变量默认是非空类型。当某个变量的值可以为空时,必须在声明处的数据类型后添加“?”来标识该引用可为空。var name...

android.view.ViewRootImpl$CalledFromWrongThreadException

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.哎,对自己无语了,竟然一时犯了这...

蒋勋 : 孤独的乐趣

与孤独相处的时候,可以多一点思维的空间,生命的过程会不会更细腻一点?——蒋勋禅宗有一则有趣的故事,小徒弟整天跟老师父说:“我心不安,我心不安。”他觉得心好慌,上课没有心上课,做功课没有心做功课,问老师父到底该怎么办?师父拿出一把刀,说:“心拿出来,我帮你安一安。”心一直在自己身上,心会不安,是被...

海子:面朝大海,春暖花开

从明天起,做一个幸福的人喂马,劈柴,周游世界从明天起,关心粮食和蔬菜我有一所房子,面朝大海,春暖花开 从明天起,和每一个亲人通信告诉他们我的幸福那幸福的闪电告诉我的我将告诉每一个人 给每一条河每一座山取一个温暖的名字陌生人,我也为你祝福愿你有一个灿烂的前程...