1 创建联结
WHERE子句的重要性:
⚠️ 要保证所有联结都有WHERE子句,否则DBMS将返回比想要的数据多得多的数据。
⚠️ 同理,要保证WHERE子句的正确性。不正确的过滤条件会导致DBMS返回不正确的数据。
叉联结(cross join):返回笛卡儿积的联结
笛卡儿积(cartesian product):由没有联结条件的表关系返回的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。
SELECT vend_name, prod_name, prod_price
FROM Vendors, Products
WHERE Vendors.vend_id = Products.vend_id;
内联结(inner join):基于两个表之间的相等测试
SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id;
注意:
虽然这两种查询在功能上可能产生相同的结果,但使用 INNER JOIN 语法有以下优势:
明确性:清楚地表明了连接的类型(内连接)。
可读性:提高了查询的可读性,使得其他开发者更容易理解查询的意图。
扩展性:更容易扩展到更复杂的连接类型,如左连接、右连接等。
因此,推荐使用 INNER JOIN 语法,因为它更符合现代 SQL 标准,更易于维护和扩展。
联结多个表
⚠️ SQL不限制一条SELECT语句中可以联结的表的数目
/* 前面采用子查询 */
SELECT cust_name, cust_contact
FROM Customers
WHERE cust_id IN (SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num
FROM OrderItems
WHERE prod_id = 'RGAN01'));
/* 等价于子查询的联结查询 */
SELECT cust_name, cust_contact
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
AND OrderItems.order_num = Orders.order_num
AND prod_id = 'RGAN01';
⚠️ 性能警告:DBMS在运行时关联指定的每个表,以处理联结。这种处理可能非常耗费资源,因此应该注意,不要联结不必要的表。联结的表越多,性能下降越厉害。
2 创建高级联结
SQL除了可以对列名和计算字段使用别名,还允许给表名起别名。这样做有两个主要理由:
缩短SQL语句;
允许在一条SELECT语句中多次使用相同的表。
SELECT cust_name, cust_contact
FROM Customers AS C, Orders AS O, OrderItems AS OI
WHERE C.cust_id = O.cust_id
AND OI.order_num = O.order_num
AND prod_id = 'RGAN01';
不同类型的联结:
自联结(self-join):它将同一个表视为两个不同的表进行联结,基于表中某个列的值来匹配行
自然联结(natural join):自动基于两个表中具有相同列名的字段来进行联接,而无需显式指定连接条件
外联结 (outer join):会返回左表、右表或两个表中的所有行,即使在另一个表中没有匹配的行。
左外联结(LEFT OUTER JOIN):
返回左表(指定的表)的所有行。
如果左表中的行在右表中有匹配的行,则返回匹配的行;否则,返回 NULL 值。
右外联结(RIGHT OUTER JOIN):
返回右表的所有行。
如果右表中的行在左表中有匹配的行,则返回匹配的行;否则,返回 NULL 值
全外联结FULL OUTER JOIN):
返回左表和右表中的所有行。
如果某个表中的行在另一个表中有匹配的行,则返回匹配的行;否则,返回 NULL 值。
关键字INNER JOIN、OUTER JOIN指定联结类型,不是在WHERE子句中指定。
SELECT Customers.cust_id, Orders.order_num
FROM Customers LEFT OUTER JOIN Orders
ON Customers.cust_id = Orders.cust_id;
3 带有聚合函数的联结
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;
我是文熠,一个正在找工作的95后算法工程师