《卸甲笔记》-PostgreSQL和Oracle的SQL差异分析之一:外连接

本文涉及的产品
PolarDB Agent Express,2核4GB
云数据库 PolarDB MySQL 版,列存表分析加速 4核8GB
简介:

PostgreSQL是世界上功能最强大的开源数据库,在国内得到了越来越多机构和开发者的青睐和应用。随着PostgreSQL的应用越来越广泛,Oracle向PostgreSQL数据库的数据迁移需求也越来越多。数据库之间数据迁移的时候,首先是迁移数据,然后就是SQL、存储过程、序列等程序中不同的数据库中数据的使用方式的转换。下面根据自己的理解和测试,写了一些SQL以及数据库对象转换方面的文章,不足之处,尚请多多指教。

外连接

Oracle数据库中,数据的外连接有两种写法。一种是标准SQL的写法。【left (outer) join XXX on】。这种标准写法Oracle和PostgreSQL都是支持的。但是,Oracle还有自己的一种写法,就是(+)。这种写法PostgreSQL不支持。所以数据迁移过来以后,需要将Oracle的这种特有的SQL写法转换成PostgreSQL支持的写法,程序才能够在PostgreSQL数据库中正常的运行。下面利用下面的表数据分析一下Oracle的这种外连接的写法和转换的方式。

SQL> select * from employ;

        ID NAME              AGE ADDR
---------- ---------- ---------- --------------------
         1 赵大               20 山东济南
         2 钱二               20 山东青岛
         4 李四               20 山东济南
         5 周五               20 山东日照

SQL> select * from salary;

     EMPID YYMM       SALARY
---------- ------ ----------
         1 200010       6000
         2 200010       5000
         3 200010       7000

SQL> select * from achieve;

     EMPID YYMM      ACHIEVE
---------- ------ ----------
         1 200010     150000
         2 200010     100000
         5 200011      50000

1、左外连接

Oracle的(+)写在等号右侧的时候,表示是以等号左边的表为主表,以右侧的表为连接表的左外连接。以左侧的表为主表,右侧的表的数据如果有,则把数据取出来显示。如果没有,则 显示空(NULL)。
PostgreSQL中,可以把它转化成对应的【left (outer) join on】语句就可以了。注意两个相同的表有多个关联条件的情况(比如下面的第二个SQL)。

Oracle 左外连接
SQL> select  emp.id,  emp.Name, sal.yymm, sal.salary
  2  from employ emp, salary sal
  3  where  emp.id = sal.empid(+);

        ID NAME       YYMM       SALARY
---------- ---------- ------ ----------
         1 赵大       200010       6000
         2 钱二       200010       5000
         5 周五
         4 李四

SQL> select ach.empid, ach.yymm, ach.achieve, sal.salary
  2  from  achieve ach,  salary sal
  3  where  ach.empid=sal.empid(+)
  4  and ach.yymm=sal.yymm(+);

     EMPID YYMM      ACHIEVE     SALARY
---------- ------ ---------- ----------
         1 200010     150000       6000
         2 200010     100000       5000
         5 200011      50000
对应的PostgreSQL的SQL
postgres=# select  emp.id,  emp.Name, sal.yymm, sal.salary
postgres-# from employ emp
postgres-# left outer join salary sal on emp.id=sal.empid;
 id | name |  yymm  | salary
----+------+--------+--------
  1 | 赵大 | 200010 |   6000
  2 | 钱二 | 200010 |   5000
  5 | 周五 |        |
  4 | 李四 |        |
(4 行记录)

postgres=# select ach.empid, ach.yymm, ach.achieve, sal.salary
postgres-# from  achieve ach
postgres-# left join salary sal
postgres-# on  ach.empid=sal.empid
postgres-# and ach.yymm=sal.yymm;
 empid |  yymm  | achieve | salary
-------+--------+---------+--------
     1 | 200010 |  150000 |   6000
     2 | 200010 |  100000 |   5000
     5 | 200011 |   50000 |
(3 行记录)

2、右外连接

Oracle的(+)写在等号左侧的时候,表示是以等号右边的表为主表,以左侧的表为连接表的右外连接。以右侧的表为主表,左侧的表的数据如果有,则把数据取出来显示。如果没有,则 显示空(NULL)。
PostgreSQL中,可以把它转化成对应的【right (outer) join on】语句就可以了。

Oracle 右外连接
SQL> select  emp.id,  emp.Name, sal.yymm, sal.salary
  2  from employ emp, salary sal
  3  where  emp.id(+) = sal.empid;

        ID NAME       YYMM       SALARY
---------- ---------- ------ ----------
         1 赵大       200010       6000
         2 钱二       200010       5000
                      200010       7000

SQL> select ach.empid, ach.yymm, ach.achieve, sal.salary
  2  from  achieve ach,  salary sal
  3  where  ach.empid(+)=sal.empid
  4  and ach.yymm(+)=sal.yymm;

     EMPID YYMM      ACHIEVE     SALARY
---------- ------ ---------- ----------
         1 200010     150000       6000
         2 200010     100000       5000
                                   7000
对应的PostgreSQL的SQL
postgres=# select  emp.id,  emp.Name, sal.yymm, sal.salary
postgres-# from employ emp
postgres-# right outer join salary sal on emp.id=sal.empid;
 id | name |  yymm  | salary
----+------+--------+--------
  1 | 赵大 | 200010 |   6000
  2 | 钱二 | 200010 |   5000
    |      | 200010 |   7000
(3 行记录)

postgres=# select ach.empid, ach.yymm, ach.achieve, sal.salary
postgres-# from  achieve ach
postgres-# right join salary sal
postgres-# on  ach.empid=sal.empid
postgres-# and ach.yymm=sal.yymm;
 empid |  yymm  | achieve | salary
-------+--------+---------+--------
     1 | 200010 |  150000 |   6000
     2 | 200010 |  100000 |   5000
       |        |         |   7000
(3 行记录)

3、多个连接条件的注意事项

Oracle中,两个表通过多个关连条件外连接的时候,如果多个条件中有没有写(+)的条件,则连接会自动变成内连接,而不再是外连接。这种情况应该是属于写SQL的失误。遇到这种情况的时候一定要注意。

Oracle
SQL> select ach.empid, ach.yymm, ach.achieve, sal.salary
  2  from  achieve ach,  salary sal
  3  where  ach.empid=sal.empid
  4  and ach.yymm=sal.yymm;

     EMPID YYMM      ACHIEVE     SALARY
---------- ------ ---------- ----------
         1 200010     150000       6000
         2 200010     100000       5000

SQL> select ach.empid, ach.yymm, ach.achieve, sal.salary
  2  from  achieve ach,  salary sal
  3  where  ach.empid=sal.empid(+)
  4  and ach.yymm=sal.yymm(+);

     EMPID YYMM      ACHIEVE     SALARY
---------- ------ ---------- ----------
         1 200010     150000       6000
         2 200010     100000       5000
         5 200011      50000

SQL> select ach.empid, ach.yymm, ach.achieve, sal.salary
  2  from  achieve ach,  salary sal
  3  where  ach.empid=sal.empid(+)
  4  and ach.yymm=sal.yymm;

     EMPID YYMM      ACHIEVE     SALARY
---------- ------ ---------- ----------
         1 200010     150000       6000
         2 200010     100000       5000
对应的PostgreSQL的SQL
postgres=# select ach.empid, ach.yymm, ach.achieve, sal.salary
postgres-# from  achieve ach
postgres-# left join salary sal
postgres-# on  ach.empid=sal.empid
postgres-# and ach.yymm=sal.yymm;
 empid |  yymm  | achieve | salary
-------+--------+---------+--------
     1 | 200010 |  150000 |   6000
     2 | 200010 |  100000 |   5000
     5 | 200011 |   50000 |
(3 行记录)

postgres=# select ach.empid, ach.yymm, ach.achieve, sal.salary
postgres-# from  achieve ach, salary sal
postgres-# where ach.empid=sal.empid
postgres-# and ach.yymm=sal.yymm;
 empid |  yymm  | achieve | salary
-------+--------+---------+--------
     1 | 200010 |  150000 |   6000
     2 | 200010 |  100000 |   5000
(2 行记录)
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
8月前
|
SQL 数据可视化 关系型数据库
MCP与PolarDB集成技术分析:降低SQL门槛与简化数据可视化流程的机制解析
阿里云PolarDB与MCP协议融合,打造“自然语言即分析”的新范式。通过云原生数据库与标准化AI接口协同,实现零代码、分钟级从数据到可视化洞察,打破技术壁垒,提升分析效率99%,推动企业数据能力普惠化。
661 3
|
11月前
|
SQL 存储 关系型数据库
PostgreSQL窗口函数避坑指南:如何让复杂分析查询提速300%?
本文基于真实企业级案例,深入剖析PostgreSQL窗口函数的执行原理与性能陷阱,提供8大优化策略。通过定制索引、分区裁剪、内存调优及并行处理等手段,将分钟级查询压缩至秒级响应。结合CTE分阶段计算与物化视图技术,解决海量数据分析中的瓶颈问题。某金融客户实践表明,风险分析查询从47秒降至0.8秒,效率提升5800%。文章附带代码均在PostgreSQL 15中验证,助您高效优化SQL性能。
533 0
|
8月前
|
SQL Oracle 关系型数据库
Oracle数据库创建表空间和索引的SQL语法示例
以上SQL语法提供了一种标准方式去组织Oracle数据库内部结构,并且通过合理使用可以显著改善查询速度及整体性能。需要注意,在实际应用过程当中应该根据具体业务需求、系统资源状况以及预期目标去合理规划并调整参数设置以达到最佳效果。
555 8
|
7月前
|
SQL 关系型数据库 MySQL
为什么这些 SQL 语句逻辑相同,性能却差异巨大?
我是小假 期待与你的下一次相遇 ~
314 0
|
SQL 关系型数据库 MySQL
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路
|
11月前
|
SQL 关系型数据库 PostgreSQL
CTE vs 子查询:深入拆解PostgreSQL复杂SQL的隐藏性能差异
本文深入探讨了PostgreSQL中CTE(公共表表达式)与子查询的选择对SQL性能的影响。通过分析两者底层机制,揭示CTE的物化特性及子查询的优化融合优势,并结合多场景案例对比执行效率。最终给出决策指南,帮助开发者根据数据量、引用次数和复杂度选择最优方案,同时提供高级优化技巧和版本演进建议,助力SQL性能调优。
1271 1
|
SQL 算法 数据挖掘
【SQL周周练】:利用行车轨迹分析犯罪分子作案地点
【SQL破案系列】第一篇: 如果监控摄像头拍下了很多车辆的行车轨迹,那么如何利用这些行车轨迹来分析车辆运行的特征,是不是能够分析出犯罪分子“踩点”的位置
312 15
|
SQL 关系型数据库 MySQL
【MySQL】SQL分析的几种方法
以上就是SQL分析的几种方法。需要注意的是,这些方法并不是孤立的,而是相互关联的。在实际的SQL分析中,我们通常需要结合使用这些方法,才能找出最佳的优化策略。同时,SQL分析也需要对数据库管理系统,数据,业务需求有深入的理解,这需要时间和经验的积累。
440 12
|
SQL Oracle 关系型数据库
解决大小写、保留字与特殊字符问题!Oracle双引号在SQL中的特殊应用
在Oracle数据库开发中,双引号的使用是一个重要但易被忽视的细节。本文全面解析了双引号在SQL中的特殊应用场景,包括解决标识符与保留字冲突、强制保留大小写、支持特殊字符和数字开头标识符等。同时提供了最佳实践建议,帮助开发者规避常见错误,提高代码可维护性和效率。
548 6
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法

热门文章

最新文章

推荐镜像

更多