SQL查询从一个表中返回另一个表中不存在的行

时间:2013-10-31 23:10:49

标签: sql deployment oracle11g production-environment setup-deployment

我最近犯了一个代价高昂且令人尴尬的错误,而且如果它再次发生的话,我会感到很沮丧。我希望你能帮助我......这就是发生的事。

在PROD的部署中,其中一个步骤是确保DEV.code_mapping表中存在所有PROD.code_mapping表行。

为此,我运行了以下查询(Oracle 11g)。我希望它能显示DEV.code_mapping中PROD.code_mapping中存在 not 的每一行。

select * FROM code_mapping D 
where D.source_system_id = '&LHDNUMBER'
and not exists
    (select 1 from
    dm.code_mapping@PROD_CHECK P where
    D.mapping_definition_id = P.mapping_definition_id and
    D.cdm_code = P.cdm_code and
    D.source_system_code = P.source_system_code);

查询返回零结果。

我错误地断定DEV.code_mapping中的每一行都存在于PROD.code_mapping

事实证明,实际上PROD.code_mapping表中没有任何行。该查询以某种方式没有选择它。我想这可能是因为这个查询无法对PROD中的空值进行评估,但是NVL([column],'null')语句的数量似乎无法使其正常工作。

我该如何工作?

同时

除了查询更正本身之外,我还欢迎任何最佳实践指导,你可以给我这样的承诺。我 真的 不希望再次上传。

2 个答案:

答案 0 :(得分:3)

就个人而言,我会使用MINUS

SELECT *
  FROM code_mapping
 WHERE soure_system_id = '&LHDNUMBER'
MINUS
SELECT *
  FROM dm.code_mapping@prod_check

MINUS自动处理NULL次比较(源上的NULL自动匹配目标上的NULL

如果你想要list all differences between the two tables(即列出dev中存在的所有行但不是prod和prod而不是dev),你可以添加一个UNION ALL

(SELECT a.*, 'In dev but not prod' descriptio
   FROM dev_table a
 MINUS 
 SELECT a.*, 'In dev but not prod' description
   FROM prod_table a)
UNION ALL
(SELECT a.*, 'In prod but not dev' descriptio
   FROM prod_table a
 MINUS 
 SELECT a.*, 'In prod but not dev' description
   FROM dev_table a)

答案 1 :(得分:3)

使用LEFT JOIN和WHERE myProdField为空。

所以对于你的查询,如果我正确地读你,你会得到:

SELECT D.mapping_definition_id, D.cdm_code, D.source_system_code FROM code_mapping D
LEFT JOIN dm.code_mapping@PROD_CHECK P
  ON D.mapping_definition_id = P.mapping_definition_id
    AND D.cdm_code = P.cdm_code
    AND D.source_system_code = P.source_system_code
WHERE P.mapping_definition_id IS NULL

无论如何,这是一般的想法。除非满足所有三个条件,否则它将不匹配。因此,任何区别都会为您提供一个包含P.mapping_definition_id的P字段为空的行,您要对其进行过滤。因此,这将为您提供在PROD中没有完全匹配的DEV中的每一行。

对于最佳实践指针,确保部署完全符合您的计划的最安全方法是在相同的环境中实践它。如果您能够设置一个镜像生产的预生产环境,则可以先在那里测试部署,以确保它已完成预期的操作。然后完全重复生产。