重学MYSQL之创建高级联结

数据库 2020-09-08 850

1.使用表别名

SQL除了可以对列名和计算字段使用别名,还允许给表名起别名。主要有两个原因:

  • 缩短SQL语句
  • 允许在一条SELECT语句中多次使用相同的表
SELECT title, readNum, category, category_id FROM blog_blogmodel AS blog INNER JOIN blog_blogtype AS type_ ON
blog.category_id = type_.id;

 在表名后使用AS,可以为表指定别名

注意:Oracle中没有AS,Oracle不支持AS关键字。要在Oracle中使用别名,可以不使用AS,简单的指定列名即可。(blog_blogmodel blog 就可以了)

2.使用不同类型的联结

其他联结:自联结(self-join)、自然联结(natural join)和外联结(outer join)

2.1 自联结

加入要给Jim同一公司的所有顾客发一封信件。这个查询首先找出Jim工作的公司,然后找出在该公司工作的顾客。

SELECT cust_id, cust_name, cust_contact FROM Customers WHERE cust_name = (SELECT cust_name FROM
Customers WHERE cust_contact = 'Jim');

这是第一种解决方案。内部返回Jim工作公司的cust_name.然后在查询cust_name的具体信息。

使用联结查询:

SELECT c1.cust_id, c1.cust_name, c1.cust_contact FROM c1.cust_name = c1.cust_name AND c2.cust_contact = 'Jim';

使用自联结要比使用子查询性能更高,因此更推荐使用自联结。

2.2 自然联结

标准的联结会返回所有数据,相同的列甚至多次出现。自然联结会排除多次出现,使每一列只返回一次

自然联结要求你只能选择哪些唯一的列,一般通过对一个表使用通配符(SELECT *),而对其他表的列使用明确的子集来完成。

SELECT B.*, category FROM blog_blogmodel AS B, blog_blogtype AS T WHERE B.category_id = T.id;

通配符(B.*会返回B表中的所有列)只对第一个表使用。其他列明确指出,没有重复的列被检索。

事实上,我们现在建立的每个内联结都是自然联结。

2.3 外联结

许多联结将一个表中的行与另一个表中的行相关联,但有时需要包含没有关联行的那些行(公共的行)。比如以下场景:

  • 对每个顾客下的订单进行计数,包括那些至今尚未下订单的顾客
  • 列出所有产品以及订购数量,包括没有人订购的产品
  • 计算平均销售的规模,包括那些至今尚未下订单的顾客

联结包含了那些在相关表中没有关联行的行,这种联结叫外联结。

外联结语法,检索博客表的类型与博客类型表相同的所有文章。

SELECT B.*, T.* FROM blog_blogmodel AS B LEFT OUTER JOIN blog_blogtype AS T ON B.category_id = T.id;

效果:

你可能没办法看出效果,因为设置了外键的缘故。

通过右连接你就看出端倪了

SELECT B.*, T.* FROM blog_blogmodel AS B RIGHT OUTER JOIN blog_blogtype AS T ON B.category_id = T.id;

效果:

你会发现这时的行数是以博客类型表为主,且没有使用博客类型的博客文章,也被查出来了

在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所在行的表(RIGHT指出的是OUTER JOIN右边的表,而LEFT指出的是OUTER左边的表)

注意:SQLite只有左联结,如果你希望使用右联结,可以使用左联结替代,只需要将两个表互换位置即可。

全外联结:它检索两个表中所有行并关联那些可以关联的行。与左外联结或右外联结包含一个表的不关联的行不同,全外联结包含两个表的不关联的行。

SELECT Customers.cust_id, Orders.order_num FROM Orders FULL OUTER JOIN Customers ON Orders.cust_id = Customers.cust_id;

注意:Access,MariaDB,MySQL,Open Office Base和SQLite不支持全连接。

3.使用带聚集函数的联结

检索所有顾客及每个顾客所下的订单数,下面的代码使用COUNT()函数完成工作

SELECT Customers.cust_id, COUNT(Orders.order_num) AS num_ord FROM Customers.cust_id = Orders.cust_id GROUP BY Customers.cust_id;

SELECT 语句使用INNER JOIN将Customers和Orders表互相关联,GROUP BY子句按顾客分组数据,因此调用COUNT(Orders.order_num)对每个顾客的订单计数。

联结间的区别

标签:数据库

文章评论

评论列表

已有0条评论