解决:Oracle数据库中Left join on 后面为null时匹配不上

简介: 解决:Oracle数据库中Left join on 后面为null时匹配不上
+关注继续查看

1:记录

最近在公司开发遇到一个小需求,在级联查询时, 当ON.... AND .... 时,ON后面的条件为NULL ,AND 后面的条件不为NULL。要求返回A表与B表匹配上的数据。

2:遇到问题

  当ON 后面的条件为NULL,AND 后的条件不为NULL。

 例:

ON NULL = NULL AND 6 = 6

    使用级联查询时,只返回主表中的数据,次表中的数据却没有匹配上显示都是NULL(可是明明都有数据)

3:解决过程

3.1 临时表A

SQL:

SELECT 
            PROD_TYPE,
            CAST(COUNT(WORK_ORDER_ID) AS float) AS 计划数量,
            SUBSTR(START_DATE, 1, 7)            AS START_DATE,
 
            MAX(TO_CHAR(DATA_TIME, 'YYYY-MM'))  AS 统计日期,
            MAX(STAT_TIME)                      AS 创建时间
     FROM DWS_WORK_ORDER_INFO
     GROUP BY SUBSTR(START_DATE, 1, 7), PROD_TYPE

f914c6172da248c7aaf70be022aff99d.png

3.2  临时表B

SQL:

 SELECT CAST(COUNT(WORK_ORDER_ID) AS float) AS 完成数量,
           SUBSTR(START_DATE,1,7)      AS START_DATE,
           PROD_TYPE
    FROM BRAIN.DWS_WORK_ORDER_INFO
    WHERE IF_COMP = '是'
    GROUP BY SUBSTR(START_DATE,1,7), PROD_TYPE

0537ca910a004c6e9b364665bffbafad.png此时我想通过LEFT JOIN 左关联查出  PROD_TYPE = NULL  时的计划数量和完成数量关联条件为:

ON a.PROD_TYPE = b.PROD_TYPE
AND a.START_DATE = b.START_DATE

3.3 错误SQL(不符合需求)

 
select
    a.计划数量,
    a.PROD_TYPE,
    b.PROD_TYPE,
    a.START_DATE,
    b.START_DATE,
    b.完成数量
 
from(SELECT 
            PROD_TYPE,
            CAST(COUNT(WORK_ORDER_ID) AS float) AS 计划数量,
            SUBSTR(START_DATE, 1, 7)            AS START_DATE,
 
            MAX(TO_CHAR(DATA_TIME, 'YYYY-MM'))  AS 统计日期,
            MAX(STAT_TIME)                      AS 创建时间
     FROM DWS_WORK_ORDER_INFO
     GROUP BY SUBSTR(START_DATE, 1, 7), PROD_TYPE) a
         LEFT JOIN (
    --已完成
    SELECT CAST(COUNT(WORK_ORDER_ID) AS float) AS 完成数量,
           SUBSTR(START_DATE,1,7)      AS START_DATE,
           PROD_TYPE
    FROM DWS_WORK_ORDER_INFO
    WHERE IF_COMP = '是'
    GROUP BY SUBSTR(START_DATE,1,7), PROD_TYPE ) b
             ON  a.PROD_TYPE = b.PROD_TYPE
            AND a.START_DATE = b.START_DATE

执行后的结果:

很明显2023-10月的 PROD_TYPE为null 时 临时表B的数据没有匹配上,后来查询资料发现,联表查询时,null≠null

72b0e0db6dd4408d80bd14cd35ded942.png

 4:解决方法

这里可以使用 NVL() ,IFNULL(), 函数均可以
 
COALESCE(a.PROD_TYPE,-1) = COALESCE(b.PROD_TYPE,-1)
 
select
    a.计划数量,
    a.PROD_TYPE,
    b.PROD_TYPE,
    a.START_DATE,
    b.START_DATE,
    b.完成数量
 
from(SELECT 
            PROD_TYPE,
            CAST(COUNT(WORK_ORDER_ID) AS float) AS 计划数量,
            SUBSTR(START_DATE, 1, 7)            AS START_DATE,
 
            MAX(TO_CHAR(DATA_TIME, 'YYYY-MM'))  AS 统计日期,
            MAX(STAT_TIME)                      AS 创建时间
     FROM DWS_WORK_ORDER_INFO
     GROUP BY SUBSTR(START_DATE, 1, 7), PROD_TYPE) a
         LEFT JOIN (
    --已完成
    SELECT CAST(COUNT(WORK_ORDER_ID) AS float) AS 完成数量,
           SUBSTR(START_DATE,1,7)      AS START_DATE,
           PROD_TYPE
    FROM DWS_WORK_ORDER_INFO
    WHERE IF_COMP = '是'
    GROUP BY SUBSTR(START_DATE,1,7), PROD_TYPE ) b
             -- 这里可以使用 NVL() ,IFNULL() 函数均可以
             ON  COALESCE(a.PROD_TYPE,-1) = COALESCE(b.PROD_TYPE,-1)
            AND a.START_DATE = b.START_DATE

执行结果:

9593ad967d7f4549869ef6a2b80271cb.png

目录
相关文章
|
1月前
|
Oracle 关系型数据库
ORACLE中null的排序问题
ORACLE中null的排序问题
|
4月前
|
Oracle 关系型数据库 数据库
一篇文章带你了解Oracle 数据库中 CROSS JOIN(cross join) 语法的作用
一篇文章带你了解Oracle 数据库中 CROSS JOIN(cross join) 语法的作用
104 0
|
9月前
|
SQL 分布式计算 运维
【大数据开发运维解决方案】sqoop增量导入oracle/mysql数据到hive时时间字段为null处理
前面几篇文章详细介绍了sqoop全量增量导入数据到hive,大家可以看到我导入的数据如果有时间字段的话我都是在hive指定成了string类型,虽然这样可以处理掉时间字段在hive为空的问题,但是在kylin创建增量cube时需要指定一个时间字段来做增量,所以上面那种方式不行,这里的处理方式为把string改成timestamp类型,看实验:
【大数据开发运维解决方案】sqoop增量导入oracle/mysql数据到hive时时间字段为null处理
|
SQL Oracle 关系型数据库
oracle left join ... on 后跟条件不生效
oracle left join ... on 后跟条件,结果集过滤不生效
926 0
|
Oracle 关系型数据库 Linux
Oracle 左连接(left join) 排序问题
项目环境:linux、tomcat8.5、SSM框架、oracle11g 项目中一个列表查询,使用了左连接(left join),类似这样: select * from A left join B on A.
2622 0
|
SQL Oracle 关系型数据库
Oracle中表连接方式(Nested Loop、Hash join)对于表访问次数的测试
介绍了sql多表连接的几种方式,如有不正确的地方请指正。
4212 0
推荐文章
更多
推荐镜像
更多