文章目录

  • MySQL别名
  • 1.MySQL列的别名
  • 2.给表起别名
  • 表连接
  • 1.where字句连接
  • 2. INNER JOIN
  • 3. LEFT JOIN
  • 4. CROSS JOIN
  • 5. 自连接
  • 6. UNION
  • UNION规则
  • UNION 与UNION ALL
  • UNION与ORDER BY子句结合
  • 练习


MySQL别名

1.MySQL列的别名

  • 给表达式起列名
    有时,select语句中会包含一些表达式,为了更好地理解这些表达式的含义,增加可读性,需要给表达式起一个列名,以下是它的基本语法:

SELECT
[column_1 | expression] AS descriptive_name
FROM table_name;

  • 引用列别名
    在MySQL中,ORDER BY,GROUP BY和HAVING子句中可以使用列别名来引用该列,但是where字句中不可以引用列别名。
    补充:若列名包含空格,则列名要加上单引号。 AS也可省略不写。
    示例:利用orderdetails表,按订单号列出每个订单下的销售额,并且要求销售额大于50000。

SELECT orderNumber AS orN,SUM(priceEach*quantityOrdered) AS sales
FROM orderdetails
GROUP BY orN
HAVING sales > 50000
ORDER BY sales DESC

2.给表起别名

table_name AS table_alias

  • 引用表别名
  • 一般在INNER JOIN,LEFT JOIN,self join子句中使用表别名来简化代码(见INNER JOIN的示例)
  • 还可以用在selec的t列表, ORDER BY,GROUP BY和HAVING等字句中。

表连接

1.where字句连接

SELECT ordt.orderNumber,status
FROM orderdetails AS ordt,orders AS ord
WHERE ordt.orderNumber = ord.orderNumber

  • 若select中的列来自多个表,则需要指定该列来自哪个表
  • where子句也可以连接多个表,用and连接即可

2. INNER JOIN

内连接也称为等值连接,它基于两个表之间的相等测试

SELECT column_list
FROM t1
INNER JOIN t2 ON join_condition
INNER JOIN t3 ON join_condition2

WHERE where_conditions

  • 首先,在FROM子句中指定主表。
  • 其次,表中要连接的主表应该出现在INNER JOIN子句中。理论上说,可以连接多个其他表。 但是,为了获得更好的性能,应该限制要连接的表的数量(最好不要超过三个表)。
  • 第三,连接条件或连接谓词。连接条件出现在INNER JOIN子句的ON关键字之后。连接条件是将主表中的行与其他表中的行进行匹配的规则。
  • 连接原理:第一个表的每一行与第二个表中的每一行匹配,直到遍历完第二个表,接着第一个表的每一行与第二个表中的每一行匹配,直到遍历完第二个表,再重复以上操作,直到第一个表也遍历完成。

示例:连接orderdetails和orders表并使用表别名。

SELECT *
FROM orderdetails As ordt
INNER JOIN orders AS ord
ON ordt.orderNumber=ord.orderNumber

3. LEFT JOIN

LEFT JOIN子句允许从匹配的左右表中查询选择行记录,连接左表(t1)中的所有行,即使在右表(t2)中找不到匹配的行也显示出来,但使用NULL值代替。

SELECT
t1.c1, t1.c2, t2.c1, t2.c2
FROM
t1
LEFT JOIN
t2 ON t1.c1 = t2.c1;

4. CROSS JOIN

cross join是笛卡尔积,就是不加条件限制,即没有on字句的连接。该连接返回的行数为两个表行数的乘积。

SELECT *
FROM T1
CROSS JOIN
T2;

如果添加了WHERE子句,如果T1和T2有关系,则CROSS JOIN的工作方式与INNER JOIN子句类似。

SELECT *
FROM T1
CROSS JOIN
T2
WHERE
T1.id = T2.id;

5. 自连接

  • 当您想将表中行与同一表中的其他行组合时,可以使用自连接。要执行自联接操作必须使用表别名来帮助MySQL在单个查询中区分左表与同一张表的右表。
  • 为了更加直接地理解自连接,下面将通过一个例子来帮助你来理解。
    示例:在employees表中,employeeNumber 和report to 有重复值,这是因为下级的上一级还有他自己上一级的领导,所以这两列是有重复值的,那么假如我想知道所有上级领导直接管理的下级员工,要怎么实现这个查询呢?
    思路:若是我们可以复制一份empolyees表,然后将这两个表的report to和employeeNumber字段连接,就可以找出管理者的姓名和它的直属员工的姓名,这也是一种解决方法。在这里我们也可以使用自连接,将表自己跟自己连接,而不用再去复制它。用自连接实现过程如下:

SELECT *
FROM employees a
INNER JOIN
employees b
ON
a.reportsTo=b.employeeNumber

mysql 连接clickhouse MySQL 连接串 支持别名_Email


从上图可以看到左半部分的表时员工,右半部分的表是管理者

接下来我们提取他们的名字

SELECT CONCAT(a.lastName," “,a.firstName) AS employee,
CONCAT(b.lastName,” ",b.firstName) AS manager
FROM employees a
INNER JOIN
employees b
ON
a.reportsTo=b.employeeNumber

结果如下:

mysql 连接clickhouse MySQL 连接串 支持别名_自连接_02

6. UNION

union组合查询可以将多条select语句的结果组合成一个结果集。相当于将多个表按相同字段值纵向联结。

SELECT 列名称 FROM 表名称 UNION SELECT 列名称 FROM 表名称 ORDER BY 列名称;
SELECT 列名称 FROM 表名称 UNION ALL SELECT 列名称 FROM 表名称 ORDER BY 列名称;

UNION规则

  1. 必须由两条或两条以上的select语句组成,语句之间用关键字UNION分隔因此如果有四条语句,则要使用三个UNION。
  2. UNION中的每个查询必须至少包含有一个相同的列、表达式或聚集函数
  3. 列数据类型必须兼容,类型不必完全相同,但必须是DBMS可以隐含转换的数据类型。(因为有时候要把两个不同列的数据合并为一列)

UNION 与UNION ALL

UNION默认消除重复行,若要匹配到所有行,需使用 UNION ALL。

UNION与ORDER BY子句结合

在使用UNION组合查询时,只允许使用使用一条ORDER BY子句,而且它必须位于最后一句select语句之后,这样操作的含义是对组合的结果集进行排序,组合查询不能对单个SELECT语句排序。

练习

项目五:组合两张表 (难度:简单)
在数据库中创建表1和表2,并各插入三行数据(自己造)
表1: Person
±------------±--------+
| 列名 | 类型 |
±------------±--------+
| PersonId | int |
| FirstName | varchar |
| LastName | varchar |
±------------±--------+
PersonId 是上表主键

表2: Address
±------------±--------+
| 列名 | 类型 |
±------------±--------+
| AddressId | int |
| PersonId | int |
| City | varchar |
| State | varchar |
±------------±--------+
AddressId 是上表主键

编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:FirstName, LastName, City, State。

创建表代码

CREATE TABLE Person(
PersonId INT PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50)
)

INSERT INTO Person
VALUES(1,“a”,“A”),
(2,“b”,“B”),
(3,“c”,“C”)

CREATE TABLE Address(
Addressid INT PRIMARY KEY,
Personid INT,
City VARCHAR(8),
State VARCHAR(20)
)

INSERT INTO Address
VALUES(1.1,1,“china”,“Asia”),
(2.2,2,“english”,“Europe”),
(4.4,4,“america”,“America”)

查询代码

SELECT Person.Personid,FirstName,LastName,City,State
FROM Person
LEFT JOIN
Address
ON
Person.Personid=Address.Personid

输出结果

mysql 连接clickhouse MySQL 连接串 支持别名_自连接_03

项目六:删除重复的邮箱(难度:简单)
编写一个 SQL 查询,来删除 email 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。
±—±--------+
| Id | Email |
±—±--------+
| 1 | a@b.com |
| 2 | c@d.com |
| 3 | a@b.com |
±—±--------+
Id 是这个表的主键。
例如,在运行你的查询语句之后,上面的 Email表应返回以下几行:
±—±-----------------+
| Id | Email |
±—±-----------------+
| 1 | a@b.com |
| 2 | c@d.com |
±—±-----------------+

DELETE FROM email
WHERE ID NOT in(
SELECT ID_min FROM(
SELECT Email,MIN(Id) AS ID_min
FROM email
GROUP BY Email
) AS a
)

SELECT * FROM email

输出结果:

mysql 连接clickhouse MySQL 连接串 支持别名_Email_04