SQL 左连接
连接用于根据它们之间的逻辑关系从两个或多个表中检索记录。这个关系是使用连接条件来定义的。正如我们在前几章中所讨论的那样,连接有两种类型−
- 内连接
- 外连接
左连接是一种外连接类型,它检索第一个表中的所有记录并将它们与第二个表中的记录进行匹配。首先,让我们了解什么是外连接。
什么是外连接
外连接用于将多个数据库表连接成一个组合结果集,其中包括所有记录,即使它们不满足连接条件。在不满足连接条件的记录中,会显示NULL值。
只有在左表(或第一个表)的记录多于右表(或第二个表)的记录,或者反之,才会发生这种情况。
有三种类型的外连接,它们是−
- 左(外)连接: 检索第一个表中的所有记录,与第二个表中的匹配记录和未匹配行中的NULL值。
- 右(外)连接 : 检索第二个表中的所有记录,与第一个表中的匹配记录和未匹配行中的NULL值。
- 完全(外)连接 : 检索两个表的记录,并将未匹配的值填充为NULL。
下图说明了两个表(EmpDetails和MaritalStatus)之间的各种外连接情况。在这里,连接操作是基于连接谓词 EmpDetails.EmpID = MaritalStatus.EmpID.
SQL左连接
在SQL中,左连接或左外连接将两个或更多个表合并在一起,其中第一个表将被完整返回,但只有匹配的记录会从后续表中检索出来。如果在后续表中没有匹配到记录,连接仍然会返回一行结果,但右表的每一列都为空值(NULL)。
如果第一个表中的行数少于第二个表中的行数,则结果中将丢弃第二个表中那些在第一个表中没有对应项的行。
语法
下面是SQL中Left Join的基本语法 –
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name = table2.column_name;
示例
为了更好地理解这个查询,让我们在一个现有的数据库中创建一些表,并使用左连接或左外连接将它们连接起来。
假设我们使用以下查询创建了一个名为 CUSTOMERS 的表,其中包含了顾客的个人详细信息,包括姓名、年龄、地址和工资。
CREATE TABLE CUSTOMERS (
ID INT NOT NULL,
NAME VARCHAR (20) NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR (25),
SALARY DECIMAL (18, 2),
PRIMARY KEY (ID)
);
现在,使用INSERT语句将值插入到该表中,如下所示 –
INSERT INTO CUSTOMERS VALUES
(1, 'Ramesh', 32, 'Ahmedabad', 2000.00 ),
(2, 'Khilan', 25, 'Delhi', 1500.00 ),
(3, 'Kaushik', 23, 'Kota', 2000.00 ),
(4, 'Chaitali', 25, 'Mumbai', 6500.00 ),
(5, 'Hardik', 27, 'Bhopal', 8500.00 ),
(6, 'Komal', 22, 'MP', 4500.00 ),
(7, 'Muffy', 24, 'Indore', 10000.00 );
表将会被创建为 –
ID | NAME | AGE | ADDRESS | SALARY |
---|---|---|---|---|
1 | Ramesh | 32 | Ahmedabad | 2000.00 |
2 | Khilan | 25 | Delhi | 1500.00 |
3 | Kaushik | 23 | Kota | 2000.00 |
4 | Chaitali | 25 | Mumbai | 6500.00 |
5 | Hardik | 27 | Bhopal | 8500.00 |
6 | Komal | 22 | MP | 4500.00 |
7 | Muffy | 24 | Indore | 10000.00 |
让我们创建另一个表 ORDERS ,其中包含订单的详细信息以及下单日期。
CREATE TABLE ORDERS (
OID INT NOT NULL,
DATE VARCHAR (20) NOT NULL,
CUSTOMER_ID INT NOT NULL,
AMOUNT DECIMAL (18, 2)
);
使用INSERT语句,将值插入到该表中,如下所示 –
INSERT INTO ORDERS VALUES
(102, '2009-10-08 00:00:00', 3, 3000.00),
(100, '2009-10-08 00:00:00', 3, 1500.00),
(101, '2009-11-20 00:00:00', 2, 1560.00),
(103, '2008-05-20 00:00:00', 4, 2060.00);
表格显示如下:
OID | DATE | CUSTOMER_ID | AMOUNT |
---|---|---|---|
102 | 2009-10-08 00:00:00 | 3 | 3000.00 |
100 | 2009-10-08 00:00:00 | 3 | 1500.00 |
101 | 2009-11-20 00:00:00 | 2 | 1560.00 |
103 | 2008-05-20 00:00:00 | 4 | 2060.00 |
以下是 左连接查询 ,检索在指定日期下订单的客户的详细信息和没有下订单的客户的详细信息。如果没有找到匹配项,以下查询将在该记录中返回NULL。
SELECT ID, NAME, AMOUNT, DATE
FROM CUSTOMERS
LEFT JOIN ORDERS
ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
输出
得到的结果表如下 –
ID | NAME | AMOUNT | DATE |
---|---|---|---|
1 | Ramesh | NULL | NULL |
2 | Khilan | 1560.00 | 2009-11-20 00:00:00 |
3 | Kaushik | 1500.00 | 2009-10-08 00:00:00 |
3 | Kaushik | 3000.00 | 2009-10-08 00:00:00 |
4 | Chaitali | 2060.00 | 2008-05-20 00:00:00 |
5 | Hardik | NULL | NULL |
6 | Komal | NULL | NULL |
7 | Muffy | NULL | NULL |
如上表所示,在ORDERS表中只有Khilan、Kaushik和Chaitali在指定日期购买了商品;因此,这些记录是匹配的。而在CUSTOMERS表中的其他顾客在指定日期没有购买商品,所以这些记录返回为NULL。
使用左连接连接多个表
与内连接查询类似,左连接也是连接多个表,其中第一个表保持不变,剩余的表与第一个表的行匹配。如果记录没有匹配,将返回NULL。
使用左连接连接多个表的语法如下:
SELECT column1, column2, column3...
FROM table1
LEFT JOIN table2
ON condition_1
LEFT JOIN table3
ON condition_2
....
....
LEFT JOIN tableN
ON condition_N;
示例
为了演示使用多个表的左连接,我们将考虑之前创建的CUSTOMERS和ORDERS表。除此之外,我们将使用以下查询创建EMPLOYEE表。
CREATE TABLE EMPLOYEE (
EID INT NOT NULL,
EMPLOYEE_NAME VARCHAR (30) NOT NULL,
SALES_MADE DECIMAL (20)
);
现在,我们可以使用INSERT语句将值插入到这个空表中,如下所示−
INSERT INTO EMPLOYEE VALUES
(102, 'SARIKA', 4500),
(100, 'ALEKHYA', 3623),
(101, 'REVATHI', 1291),
(103, 'VIVEK', 3426);
EMPLOYEE表包含组织中员工的详细信息以及他们所进行的销售。
EID | EMPLOYEE_NAME | SALES_MADE |
---|---|---|
102 | SARIKA | 4500 |
100 | ALEKHYA | 3623 |
101 | REVATHI | 1291 |
103 | VIVEK | 3426 |
100 | ALEKHYA | 3456 |
以下查询使用左连接将CUSTOMERS、ORDERS和EMPLOYEE表连接起来:
SELECT CUSTOMERS.ID, CUSTOMERS.NAME, ORDERS.DATE, EMPLOYEE.EMPLOYEE_NAME
FROM CUSTOMERS
LEFT JOIN ORDERS
ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
LEFT JOIN EMPLOYEE
ON ORDERS.OID = EMPLOYEE.EID;
通过这个查询,我们将显示顾客的id和姓名,以及订单的日期和销售该商品的员工的姓名。
输出
得到下面的结果表:
ID | NAME | DATE | EMPLOYEE_NAME |
---|---|---|---|
1 | Ramesh | NULL | NULL |
2 | Khilan | 2009-11-20 00:00:00 | REVATHI |
3 | Kaushik | 2009-10-08 00:00:00 | ALEKHYA |
3 | Kaushik | 2009-10-08 00:00:00 | ALEKHYA |
3 | Kaushik | 2009-10-08 00:00:00 | SARIKA |
4 | Chaitali | 2008-05-20 00:00:00 | VIVEK |
5 | Hardik | NULL | NULL |
6 | Komal | NULL | NULL |
7 | Muffy | NULL | NULL |
如上表所示,顾客Kaushik共下了三个订单,其中两个由员工Alekhya销售,一个由Sarika销售。Khilan和Chaitali分别下了一个订单,分别由Revathi和Vivek销售。订单的日期也会显示出来。如果订单不是在特定的日期下的,将返回NULL。
使用WHERE子句的左连接
在执行左连接后,可以使用WHERE子句对获取的结果集进行过滤。
语法
当与WHERE子句一起使用时,左连接的语法如下所示:
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name = table2.column_name
WHERE condition;
示例
可以使用WHERE子句对组合数据库表中的记录进行过滤。考虑以前的两个表CUSTOMERS和ORDERS;使用左连接查询将它们连接起来,并使用WHERE子句应用一些约束。
SELECT ID, NAME, DATE, AMOUNT FROM CUSTOMERS
LEFT JOIN ORDERS
ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
WHERE ORDERS.AMOUNT > 2000.00;
输出
应用左连接后,应用where子句的结果表包含了金额大于2000.00的行−
ID | NAME | DATE | AMOUNT |
---|---|---|---|
3 | Kaushik | 2009-10-08 00:00:00 | 3000.00 |
4 | Chaitali | 2008-05-20 00:00:00 | 2060.00 |