【发布时间】:2016-08-17 06:11:30
【问题描述】:
我有一个从外部源加载数据的主表。主表-PROD_MAIN的表结构是
PROD_ROW_ID | PROD_VALUE | PROD_TYPE | PROD_DATE
数据从主表加载到另外两个表中。这两个表是:
PROD, PROD_ENT
- PROD_ROW_ID,PROD_TYPE 被加载到 PROD 表中并
- PROD_VALUE,PROD_DATE 已加载到 PROD_ENT
PROD 和 PROD_ENT 表使用以下条件连接。
PROD.PROD_ROW_ID = PROD_ENT.PROD_PAR_ID
每天都会将数据从 PROD_MAIN 插入到这两个表 PROD 和 PROD_ENT 表中。由于一些数据库问题,许多记录错过了加载到 PROD 和 PROD_ENT 表中。
所以,我需要检查 3 个月的缺失记录,即从 11 月 19 日到 2 月 19 日;没有加载到 PROD 和 PROD_ENT 表中。 所有这些表都有大约 2 亿条记录。
所以,我编写了以下查询来获取结果。但是它给了我零记录。你能帮忙吗?
SELECT /*+ PARALLEL (PROD_MAIN,15) */ MH.*
FROM PROD PMN,
PROD_ENT PCH,
PROD_MAIN MH
WHERE PMN.PROD_ROW_ID = PCH.PROD_PAR_ID
AND MH.PROD_ROW_ID(+) = PMN.PROD_ROW_ID
AND MH.PROD_VALUE(+) = PCH.PROD_VALUE
AND MH.PROD_TYPE(+) = PMN.PROD_TYPE
AND MH.PROD_DATE (+) = PCH.PROD_DATE
AND MH.PROD_ROW_ID IS NULL
AND MH.PROD_VALUE IS NULL
AND MH.PROD_TYPE IS NULL
AND MH.PROD_DATE IS NULL
AND MH.PROD_DATE BETWEEN '19-NOV-2015' AND '19-FEB-2016'
***** 编辑代码 *****
万一, 1. 如果我需要获取在 PROD_MAIN 表中存在且在 PROD 中不存在的记录。 2. 如果我需要获取 PROD_MAIN 中存在的记录 表和 PROD_ENT 表中的 NOT PRESENT 分开,我需要编写如下的联合查询还是有其他简单的方法可以这样做?
SELECT MH.*
FROM PROD_MAIN AS MH
LEFT JOIN PROD AS PMN
ON (PMN.PROD_ROW_ID = MH.PROD_ROW_ID
AND PMN.PROD_TYPE = MH.PROD_TYPE)
LEFT JOIN PROD_ENT AS PCH
ON (PCH.PROD_PAR_ID = PMN.PROD_ROW_ID
AND PCH.PROD_DATE = MH.PROD_DATE
AND PCH.PROD_VALUE = MH.PROD_VALUE)
WHERE PMN.PROD_ROW_ID IS NULL
AND MH.PROD_DATE BETWEEN '19-NOV-2015' AND '19-FEB-2016'
UNION
SELECT MH.*
FROM PROD_MAIN AS MH
LEFT JOIN PROD AS PMN
ON (PMN.PROD_ROW_ID = MH.PROD_ROW_ID
AND PMN.PROD_TYPE = MH.PROD_TYPE)
LEFT JOIN PROD_ENT AS PCH
ON (PCH.PROD_PAR_ID = PMN.PROD_ROW_ID
AND PCH.PROD_DATE = MH.PROD_DATE
AND PCH.PROD_VALUE = MH.PROD_VALUE)
WHERE PCH.PROD_PAR_ID IS NULL
AND MH.PROD_DATE BETWEEN '19-NOV-2015' AND '19-FEB-2016'
【问题讨论】:
-
请使用显式连接语法,这是 ANSI-92 标准的一部分。老实说,我什至不明白您的联接是如何工作的,因为您使用了古怪的
(+) 表示法。但是我怀疑join可能有问题。 -
今日提示:切换到现代的、显式的 JOIN/OUTER JOIN 语法。更容易编写(没有错误)并且更容易阅读。也更容易转换为外连接。
-
在你的 where: MH.PROD_DATE 被要求为空并且在两个日期之间。不能两者都是 => 没有结果。
-
AND (MH.PROD_DATE IS NULL OR MH.PROD_DATE BETWEEN DATE '2015-11-19' AND DATE '2016-02-19') -
@Cool_Oracle:取决于您是否希望包含空值(参见 Maheswarans 评论)或排除。如果您想排除它,只需删除对 null 的检查。