【发布时间】:2010-06-02 15:26:58
【问题描述】:
这个 SQL 怎么会……
CREATE TABLE NewTable AS
SELECT A,B,C FROM Table1
minus
SELECT A, B, C From Table2
...在 A 列中创建一个具有 NULL 值的新表 当 Table1 或 Table2 在 A 列中都没有 NULL 值时?
但另一方面,这个 SQL...
SELECT * FROM
(
SELECT A,B,C FROM Table1
minus
SELECT A, B, C From Table2
)
WHERE A IS NULL
不返回任何行!
好像不一致!
我认为这是 Oracle 中的一个错误。
当然,真正的 SQL 要复杂得多,但我相信这准确地说明了问题的本质。
更新
这是实际的 SQL:
我执行了这个语句:
CREATE TABLE MyMinus
AS
select
*
FROM
---begin main query
(
SELECT expenditure_item_date, expenditure_org, expenditure_type,
f_amount_billed, f_amount_billed_fc, f_amount_billed_us,
f_bl_creation_date, f_catalog_source, f_catalog_type, f_company,
f_company_code, f_cost_center_num, f_cuic, f_currency_code,
f_destination_type_code, f_distribution_id, f_distribution_num,
f_exchange_rate, f_extract_date, f_gl_account,
f_isms_jamis_project_num, f_line_id, f_local_use, f_location_num,
f_need_by_date, f_org_id, f_po_line_num, f_po_num, f_po_release_num,
f_project, f_project_num, f_promised_date, f_quantity_billed,
f_quantity_cancelled, f_quantity_delivered, f_quantity_ordered,
f_rel_approved_flag, f_rel_cancelled_flag, f_rel_cancel_date,
f_rel_closed_code, f_rel_hold_flag, f_rel_revision_num, f_task_num
FROM dw_mgr.po_distributions_curr_fct a
WHERE EXISTS (
SELECT 1
FROM dw_mgr.po_distributions_curr_fct b,
dw_mgr.po_lines_curr_fct,
dw_mgr.po_header_curr_fct
WHERE a.ROWID = b.ROWID
AND b.f_cuic = dw_mgr.po_lines_curr_fct.f_cuic
AND b.f_line_id = dw_mgr.po_lines_curr_fct.f_line_id
AND dw_mgr.po_lines_curr_fct.f_cuic =
dw_mgr.po_header_curr_fct.f_cuic
AND dw_mgr.po_lines_curr_fct.f_header_id =
dw_mgr.po_header_curr_fct.f_header_id
AND dw_mgr.po_header_curr_fct.f_header_creation_date <
ADD_MONTHS (TRUNC (SYSDATE, 'YEAR'),
-48)
AND dw_mgr.po_header_curr_fct.f_po_status IN
('CLOSED', 'FINALLY CLOSED'))
MINUS
SELECT expenditure_item_date, expenditure_org, expenditure_type,
f_amount_billed, f_amount_billed_fc, f_amount_billed_us,
f_bl_creation_date, f_catalog_source, f_catalog_type, f_company,
f_company_code, f_cost_center_num, f_cuic, f_currency_code,
f_destination_type_code, f_distribution_id, f_distribution_num,
f_exchange_rate, f_extract_date, f_gl_account,
f_isms_jamis_project_num, f_line_id, f_local_use, f_location_num,
f_need_by_date, f_org_id, f_po_line_num, f_po_num, f_po_release_num,
f_project, f_project_num, f_promised_date, f_quantity_billed,
f_quantity_cancelled, f_quantity_delivered, f_quantity_ordered,
f_rel_approved_flag, f_rel_cancelled_flag, f_rel_cancel_date,
f_rel_closed_code, f_rel_hold_flag, f_rel_revision_num, f_task_num
FROM arch_fct.po_distributions_curr_fct a
WHERE EXISTS (
SELECT 1
FROM arch_fct.po_distributions_curr_fct b,
arch_fct.po_lines_curr_fct,
arch_fct.po_header_curr_fct
WHERE a.ROWID = b.ROWID
AND b.f_cuic = arch_fct.po_lines_curr_fct.f_cuic
AND b.f_line_id = arch_fct.po_lines_curr_fct.f_line_id
AND arch_fct.po_lines_curr_fct.f_cuic =
arch_fct.po_header_curr_fct.f_cuic
AND arch_fct.po_lines_curr_fct.f_header_id =
arch_fct.po_header_curr_fct.f_header_id
AND arch_fct.po_header_curr_fct.f_header_creation_date <
ADD_MONTHS (TRUNC (SYSDATE, 'YEAR'),
-48)
AND arch_fct.po_header_curr_fct.f_po_status IN
('CLOSED', 'FINALLY CLOSED'))
)
然后这个。请注意,已将 F_DISTRIBUTION_ID 值为 NULL 的行插入到创建的表中。
SELECT COUNT(*) from MyMinus WHERE F_DISTRIBUTION_ID IS NULL
--17 行
但是当我执行这个时:
select
*
FROM
---begin main query
(
SELECT expenditure_item_date, expenditure_org, expenditure_type,
f_amount_billed, f_amount_billed_fc, f_amount_billed_us,
f_bl_creation_date, f_catalog_source, f_catalog_type, f_company,
f_company_code, f_cost_center_num, f_cuic, f_currency_code,
f_destination_type_code, f_distribution_id, f_distribution_num,
f_exchange_rate, f_extract_date, f_gl_account,
f_isms_jamis_project_num, f_line_id, f_local_use, f_location_num,
f_need_by_date, f_org_id, f_po_line_num, f_po_num, f_po_release_num,
f_project, f_project_num, f_promised_date, f_quantity_billed,
f_quantity_cancelled, f_quantity_delivered, f_quantity_ordered,
f_rel_approved_flag, f_rel_cancelled_flag, f_rel_cancel_date,
f_rel_closed_code, f_rel_hold_flag, f_rel_revision_num, f_task_num
FROM dw_mgr.po_distributions_curr_fct a
WHERE EXISTS (
SELECT 1
FROM dw_mgr.po_distributions_curr_fct b,
dw_mgr.po_lines_curr_fct,
dw_mgr.po_header_curr_fct
WHERE a.ROWID = b.ROWID
AND b.f_cuic = dw_mgr.po_lines_curr_fct.f_cuic
AND b.f_line_id = dw_mgr.po_lines_curr_fct.f_line_id
AND dw_mgr.po_lines_curr_fct.f_cuic =
dw_mgr.po_header_curr_fct.f_cuic
AND dw_mgr.po_lines_curr_fct.f_header_id =
dw_mgr.po_header_curr_fct.f_header_id
AND dw_mgr.po_header_curr_fct.f_header_creation_date <
ADD_MONTHS (TRUNC (SYSDATE, 'YEAR'),
-48)
AND dw_mgr.po_header_curr_fct.f_po_status IN
('CLOSED', 'FINALLY CLOSED'))
MINUS
SELECT expenditure_item_date, expenditure_org, expenditure_type,
f_amount_billed, f_amount_billed_fc, f_amount_billed_us,
f_bl_creation_date, f_catalog_source, f_catalog_type, f_company,
f_company_code, f_cost_center_num, f_cuic, f_currency_code,
f_destination_type_code, f_distribution_id, f_distribution_num,
f_exchange_rate, f_extract_date, f_gl_account,
f_isms_jamis_project_num, f_line_id, f_local_use, f_location_num,
f_need_by_date, f_org_id, f_po_line_num, f_po_num, f_po_release_num,
f_project, f_project_num, f_promised_date, f_quantity_billed,
f_quantity_cancelled, f_quantity_delivered, f_quantity_ordered,
f_rel_approved_flag, f_rel_cancelled_flag, f_rel_cancel_date,
f_rel_closed_code, f_rel_hold_flag, f_rel_revision_num, f_task_num
FROM arch_fct.po_distributions_curr_fct a
WHERE EXISTS (
SELECT 1
FROM arch_fct.po_distributions_curr_fct b,
arch_fct.po_lines_curr_fct,
arch_fct.po_header_curr_fct
WHERE a.ROWID = b.ROWID
AND b.f_cuic = arch_fct.po_lines_curr_fct.f_cuic
AND b.f_line_id = arch_fct.po_lines_curr_fct.f_line_id
AND arch_fct.po_lines_curr_fct.f_cuic =
arch_fct.po_header_curr_fct.f_cuic
AND arch_fct.po_lines_curr_fct.f_header_id =
arch_fct.po_header_curr_fct.f_header_id
AND arch_fct.po_header_curr_fct.f_header_creation_date <
ADD_MONTHS (TRUNC (SYSDATE, 'YEAR'),
-48)
AND arch_fct.po_header_curr_fct.f_po_status IN
('CLOSED', 'FINALLY CLOSED'))
)
WHERE
f_distribution_id is null
我得到 0 行。
为什么将记录插入临时表似乎会引入具有 NULL DIST ID 的行?
这个由自定义数据归档程序动态生成的减号查询 SQL 尝试验证应该归档在 DW_MGR 模式中的数据实际上是否已复制到 ARCH_FCT(归档)模式。它返回的差异包括 17 条记录,其中 MyMinus 临时表中的 F_DISTRIBUTION_ID 与源 DW_MG.PO_DISTRIBUTIONS_CURR_FCT 表中的记录不匹配,因为它们为 NULL。因此,归档过程是在发现差异时设计的。问题是为什么会有差异,即当 NULL 值不在 SOURCE PO_DISTRIBUTIONS_CURR_FCT 表中时,它们是如何进入 MyMinus 表的?
编辑:
具有 Oracle META 访问权限的人能否在 Oracle 错误之后在 thd 上发布信息。我被转介给他们,但我找到了我公司的某个人,他可以告诉我我们的支持 ID # 是什么。我最终会知道的,但如果能早点知道就好了。如果您不想发布它,请考虑以下错误参考作为我的问题的潜在相关信息:
Bug 8209309: MINUS IS SHOWING DIFFERENCES WITH CTAS + INSERT
Bug 7834950: WRONG RESULTS WITH MINUS OPERATOR
【问题讨论】:
-
简短的回答是“它不能”,所以你一定做了一些微妙的不同。你能创建一个这个问题的(简单)工作示例吗?
-
我同意你的观点,我需要检查我的假设。让我们看看我是否可以做到这一点或提供更多信息来说服您和我相信以上是实际发生的情况。
-
我 99.99% 确信这是一个 Oracle 错误。我想我们可能会让 Oracle 参与确认。
-
能贴出真正的SQL吗?尽管总是有机会找到产品错误,但这里可能还有其他事情在起作用。并了解哪个版本的 Oracle 会有所帮助(如果知道,请包括主要和次要版本以及补丁级别)。谢谢,
-
只是想知道 - table1.a 的数据类型是否与 table2.a 的数据类型匹配?