南大通用大规模分布式并行数据库集群系统,简称:GBase8a MPP Cluster,它是在 GBase 8a 列存储数据库基础上开发的一款 Shared Nothing 架构的分布式并行数据库集群,具备高性能、高可用、高扩展特性,可以为超大规模数据(TB~PB级)管理提供高性价比的通用计算平台,并广泛地用于支撑各类数据仓库系统、BI系统和决策支持系统。
在 GBase 8a 中,LEFT JOIN
用于返回左表(即LEFT JOIN
关键字左边的表)的所有记录,即使在右表中没有匹配的记录。对于那些右表中没有匹配的记录,结果集中右表的部分会被填充为NULL
。关于ON
和WHERE
子句的使用,它们在LEFT JOIN
中的作用是不同的:
ON
子句:用于定义连接条件,即决定哪些记录应该被连接在一起。当你需要基于左右表的某些字段值的关系来组合记录时,这些条件应该放在ON
后面。如果在ON
后面还有对右表的额外条件限制,这些也会在连接时应用,但不会影响左表返回所有记录的原则。
WHERE
子句:用于对已经通过JOIN
操作产生的结果集进行进一步的过滤。当条件放在WHERE
子句中时,那些不符合条件的记录(无论是左表的还是右表的)都会被移除,这可能会影响到左表返回所有记录的初衷,尤其是在处理NULL
值时需格外小心。
假设我们有两个表,一个是employees(员工表),另一个是departments(部门表),我们想找出所有员工及其所在的部门名称,即使某些员工没有分配到具体的部门。
employees 表
id | name | department_id |
---|---|---|
1 | Alice | 1 |
2 | Bob | 2 |
3 | Carol | NULL |
departments 表
id | name |
---|---|
1 | HR |
2 | IT |
3 | Marketing |
其中,employees
表的department_id
字段可以是NULL
,表示没有分配部门。
使用 ON 示例
SELECT employees.name, departments.name AS department_name
FROM employees
LEFT JOIN departments ON employees.department_id = departments.id;
这个查询会返回所有员工的名字,以及他们对应的部门名字,如果员工没有部门(即department_id
为NULL
),部门名字则为NULL
。
使用 WHERE 示例
SELECT employees.name, departments.name AS department_name
FROM employees
LEFT JOIN departments ON employees.department_id = departments.id
WHERE departments.id IS NOT NULL;
这个查询试图过滤掉那些部门ID为NULL
的记录,但由于使用的是LEFT JOIN
,加上WHERE
子句过滤掉NULL
的部门ID
实际上会导致那些没有分配部门的员工也被排除在外,违反了LEFT JOIN
的初衷,即返回左表所有记录。因此,在大多数情况下,如果你想保留左表的所有记录,应避免在WHERE
子句中过滤与右表相关的NULL
值,而是应该在ON
子句中完成所有必要的连接条件和限制。
正确的做法是在ON
子句中处理所有连接条件,然后仅在确实需要进一步过滤整个结果集(而不影响左表完整性)时才使用WHERE
子句。