SQL基础8—表的联结

本文详细介绍了SQL中的表联结概念,包括等值联结、非等值联结、笛卡尔积以及内联结、外联结、自联结、自然联结的使用方法。此外,还讲解了如何创建高级联结,如使用表别名和带聚集函数的联结,并强调了正确选择和使用联结的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关键字:
- 等值联结:WHERE
- 非等值联结:WHERE
- 交叉联结cross join/笛卡尔积:无联结条件
- 内联接:[INNER] JOIN
- 外联结:LEFT/RIGHT/FULL JOIN
- 自联结:联结自身
- 多表联结:WHERE子句

引言

1.为什么要把数据分多个表进行存储?

  • 为了避免数据冗余,更加高效地进行数据处理,可伸缩性能好。
  • 可伸缩性:能够适应不断增加的工作量而不失败。

2.创建联结表的原因?

  • 联结是一种机制,用来在一条select语句中关联表,用一条语句检索出存储在多个表中的数据。

1.创建联结表

注意:完全限定列名

  • 引用的列可能会出现歧义(同名不同表),此时必须使用完全限定列名,使用表名.列名

1.1 等值联结与笛卡尔积:Where子句

Where子句的作用:

  • 作为过滤条件,只包含那些匹配给定条件的行(联结条件)。
1.等值联结

如果where子句中的限定条件为具体字段是否相等,这种联结称为等值联结。

SELECT vend_name, prod_name, prod_price
FROM Vendors, Products
Where Vendors.vend_id =  Products.vend_id;
2.非等值联结

如果where子句中的限定条件是一个区间

SELECT last_name,salary,`grade`
FROM employees e,sal_grade g
WHERE e.`salary` BETWEEN g.`min_salary` AND g.`max_salary`
AND commission_pct IS NOT NULL;
3.笛卡尔积

如果不使用Where子句:

SELECT vend_name, prod_name, prod_price
FROM Vendors, Products;

此时,第一个表中的每一行将与第二个表中的每一行配对,而不管逻辑上是否配在一起。这种联结方式,即笛卡尔积,也称交叉联结(cross join)

笛卡尔集会在下面条件下产生:

  • 省略连接条件
  • 连接条件无效
  • 所有表中的所有行互相连接

1.2 内联接:[INNER] JOIN ON

内联接等同于等值联结,但语法稍微不同:

  • 使用 JOIN 代替 FROM table1,table2
  • 使用 ON 语句代替 WHERE子句
SELECT vend_name, prod_name, prod_price
FROM Vendors INNER 
JOIN Products
ON Vendors.vend_id =  Products.vend_id;

1.3 联结多个表:Where子句

方法:

  • 首先列出表名;
  • 然后定义表之间关系。
SELECT vend_name, prod_name, prod_price,quantity
FROM Vendors, Products, OrderItems
Where Vendors.vend_id =  Products.vend_id
AND OrderItems.vend_id =  Products.vend_id
AND order_num = 20007

联结的表越多,性能下降的越厉害。

2.创建高级联结

2.1 使用表别名

可以为列名、字段名、表名起别名,其目的是

  • 缩短SQL语句;
  • 允许在一条 SELECT 语句中多次使用相同的表。
SELECT vend_name, prod_name, prod_price,quantity
FROM Vendors AS V, Products AS P, OrderItems AS O
Where V.vend_id =  P.vend_id
AND O.vend_id =  P.vend_id
AND order_num = 20007

注意:

1)Oracle中不支持AS关键字,如要使用别名,则可以直接指定即可:

  • Vendors V(而不是Vendors AS V)

2)表别名只在查询执行中使用,与列别名不一样,表别名不返回到客户端。

2.2 使用不同类型的联结

1.自联结(self join)

方法:使用同一个表的不同别名,将相同表连接在一起

SELECT c1.cust_id, c1.cust_name, c1.cust_contact
FROM Customers AS c1, Customers AS c2
WHERE c1.cust_name = c2.cust_name
AND c2.cust_contact = 'Jim Jones'

一般情况下,使用自联结而不使用子查询:

  • 许多DBMS处理联结远比处理子查询快得多。
SELECT c1.cust_id, c1.cust_name, c1.cust_contact
FROM Customers
WHERE cust_name IN (SELECT cust_name 
						FROM Customers WHERE cust_contact= 'Jim Jones');
2.自然联结(nature join)

对于联结条件中的列,只返回唯一的一列。

方法:自己在SELECT语句中设定。

3.外联结(outer join)

为何使用:

  • 当需要包含那些没有关联上的行的时候

包含:

  • left outer join
  • right outer join
  • full outer join

Access、MySQL、SQLite 不支持 FULL OUTER JOIN

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

查询:每个顾客,及顾客的下单数

SELECT Customers.cust_id, COUNT(Orders_order_num) AS num_ord
FROM Customers INNER JOIN Orders
ON Customers.cust_id = Orders.cust_id
GROUP BY Customers.cust_id;

总结:

1.使用正确的联结:

  • 注意区分自联结、内联接inner join 、外联结 outer join、全外联结 full join,以及笛卡尔积 cross join

2.注意使用正确的联结语法:

  • 应该查看具体的使用文档

3.一个联结中可以包含多个表,甚至可以对每个联结采用不同的联结类型:

  • 这样合法也很有用
  • 但应该在一起测试他们之前,分别测试每个联结。
  • 也可以使用联结进行反向筛选:左联结+右表中字段为NULL条件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值