在 PostgreSQL 连接中使用 ON 与 WHERE 子句来合并和过滤数据

发布日期:2026-07-09 05:12:02   来源 : 杭州电子商务研究院    浏览量 :2
杭州电子商务研究院 发布日期:2026-07-09 05:12:02  
2

介绍

在 SQL 查询中,可以在连接的WHERE子句或ON子句中过滤数据。本指南将研究 PostgreSQL 中两者之间的区别。

设置

为了检查在ON子句和WHERE子句中放置过滤条件之间的区别,必须创建两个可以连接在一起的表。否则无法使用ON子句。

以下代码将创建并填充两个表,一个表包含员工数据,另一个表包含部门数据,这两个表可以根据部门编号连接在一起:

      DROP TABLE IF EXISTS emp;
DROP TABLE IF EXISTS dept;

CREATE TABLE dept(
	deptno     INT,  
	dname      VARCHAR(14),  
	loc        VARCHAR(13),  
	CONSTRAINT pk_dept PRIMARY KEY(deptno)  
);

INSERT INTO dept
	(deptno, dname, loc)
VALUES
	(10, 'ACCOUNTING', 'NEW YORK'),
	(20, 'RESEARCH',   'DALLAS'),
	(30, 'SALES',      'CHICAGO'),
	(40, 'OPERATIONS', 'BOSTON')
;

CREATE TABLE emp(
	empno    INT,  
	ename    VARCHAR(10),  
	job      VARCHAR(9),  
	mgr      INT,  
	hiredate DATE,  
	sal      NUMERIC(7,2),  
	comm     NUMERIC(7,2),
	deptno   INT,
	CONSTRAINT pk_emp PRIMARY KEY(empno),  
	CONSTRAINT fk_deptno FOREIGN KEY(deptno) REFERENCES dept(deptno)
);

ALTER TABLE emp ADD CONSTRAINT fk_mgr FOREIGN KEY(mgr) REFERENCES emp(empno);

INSERT INTO emp
	(empno, ename, job, mgr, hiredate, sal, comm, deptno)
VALUES
	(7839, 'KING',  'PRESIDENT', NULL, '1981-11-17', 5000, NULL, 10),
	(7698, 'BLAKE', 'MANAGER',   7839, '1981-05-01', 2850, NULL, 30),
	(7782, 'CLARK', 'MANAGER',   7839, '1981-06-09', 2450, NULL, 10),
	(7566, 'JONES', 'MANAGER',   7839, '1981-04-02', 2975, NULL, 20),
	(7788, 'SCOTT', 'ANALYST',   7566, '1987-07-13', 3000, NULL, 20),
	(7902, 'FORD',  'ANALYST',   7566, '1981-12-03', 3000, NULL, 20)
;

COMMIT;
    

emp

员工编号 埃纳梅 工作 经理 雇用日期 萨尔 通信 部门编号
7839 国王 总统 1981-11-17 5000.00 10
7698 布莱克 经理 7839 1981-05-01 2850.00 三十
7782 克拉克 经理 7839 1981-06-09 2450.00 10
7566 琼斯 经理 7839 1981-04-02 2975.00 20
7788 斯科特 分析师 7566 0001-07-13 3000.00 20
7902 福特 分析师 7566 1981-12-03 3000.00 20

部门

部门编号 域名
10 会计 纽约
20 研究 达拉斯
三十 销售量 芝加哥
40 运营 波士顿

在内联接中使用 ON 子句与 WHERE 子句

在内连接中,在ON子句中添加过滤条件对查询结果具有相同的影响。

假设有一项业务需求,即仅当两个表中的部门编号匹配时才返回员工和部门数据,并且结果应仅包含部门名称为ACCOUNTING 的行。用户希望显示所有员工属性以及部门名称和位置。

可以编写以下三个查询来满足该要求:

      SELECT emp.*, dept.dname, dept.loc
FROM emp
INNER JOIN dept
	ON emp.deptno = dept.deptno
	AND dept.dname = 'ACCOUNTING'
;
    
      SELECT emp.*, dept.dname, dept.loc
FROM emp
INNER JOIN dept
	ON emp.deptno = dept.deptno
WHERE
	dept.dname = 'ACCOUNTING'
;
    
      SELECT emp.*, dept.dname, dept.loc
FROM emp, dept
WHERE
	emp.deptno = dept.deptno
	AND dept.dname = 'ACCOUNTING'
;
    
员工编号 埃纳梅 工作 经理 雇用日期 萨尔 通信 部门编号 域名
7839 国王 总统 1981-11-17 5000.00 10 会计 纽约
7782 克拉克 经理 7839 1981-06-09 2450.00 10 会计 纽约

无论过滤器和连接条件是放在ON子句还是WHERE子句中,所有三个查询都返回完全相同的结果。

就性能而言,过滤条件放在PostgreSQL 中的ON子句还是WHERE中都没有区别。

不过,就可读性而言,尤其是在具有多个连接的复杂查询中,将连接条件放在ON子句中更容易发现,将过滤条件放在WHERE子句中更容易发现。在上面的示例查询中,第二个查询是这样编写的。

在左连接中使用 ON 子句与 WHERE 子句

在左连接中,将过滤条件放在ON子句中会对查询结果产生不同的影响。

假设有业务需求,需要从emp表中返回所有员工,并仅查找属于ACCOUNTING部门的员工的部门信息。用户希望显示所有员工属性以及部门名称和位置。

可以通过在ON子句中放置过滤条件来满足此要求,以便在dept表与emp左连接之前根据dept.dname = 'ACCOUNTING'进行过滤

      SELECT emp.*, dept.dname, dept.loc
FROM emp
LEFT JOIN dept
	ON emp.deptno = dept.deptno
	AND dept.dname = 'ACCOUNTING'
;
    
员工编号 埃纳梅 工作 经理 雇用日期 萨尔 通信 <font style="vertical-a
以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据