【问题标题】:Oracle Natural Joins and Count(1)Oracle 自然连接和计数(1)
【发布时间】:2008-09-19 16:19:51
【问题描述】:

有谁知道为什么在 Oracle 11g 中,当您执行具有多个自然连接的 Count(1) 时,它会执行笛卡尔连接并抛出计数?

SELECT Count(1) FROM record NATURAL join address NATURAL join person WHERE status=1
AND code = 1 AND state = 'TN'

这会拉回大约 300 万行

SELECT * FROM record NATURAL join address NATURAL join person WHERE status=1
AND code = 1 AND state = 'TN'

拉回 36000 行,这是正确的数量。

我只是错过了什么吗?

这是我用来获得此结果的表格。

CREATE TABLE addresses (
address_id           NUMBER(10,0)  NOT NULL,
address_1            VARCHAR2(60)  NULL,
address_2            VARCHAR2(60)  NULL,
city                 VARCHAR2(35)  NULL,
state                CHAR(2)       NULL,
zip                  VARCHAR2(5)   NULL,
zip_4                VARCHAR2(4)   NULL,
county               VARCHAR2(35)  NULL,
phone                VARCHAR2(11)  NULL,
fax                  VARCHAR2(11)  NULL,
origin_network       NUMBER(3,0)   NOT NULL,
owner_network        NUMBER(3,0)   NOT NULL,
corrected_address_id NUMBER(10,0)  NULL,
"HASH"                 VARCHAR2(200) NULL
);

CREATE TABLE rates (
rate_id      NUMBER(10,0) NOT NULL,
eob          VARCHAR2(30) NOT NULL,
network_code NUMBER(3,0)  NOT NULL,
product_code VARCHAR2(2)  NOT NULL,
rate_type    NUMBER(1,0)  NOT NULL
);

CREATE TABLE records (
pk_unique_id      NUMBER(10,0) NOT NULL,
rate_id           NUMBER(10,0) NOT NULL,
address_id        NUMBER(10,0) NOT NULL,
effective_date    DATE         NOT NULL,
term_date         DATE         NULL,
last_update       DATE         NULL,
status            CHAR(1)      NOT NULL,
network_unique_id VARCHAR2(20) NULL,
rate_id_2         NUMBER(10,0) NULL,
contracted_by     VARCHAR2(50) NULL,
contract_version  VARCHAR2(5)  NULL,
bill_address_id   NUMBER(10,0) NULL
);

我应该提到这在 Oracle 9i 中不是问题,但是当我们切换到 11g 时,它就成了问题。

【问题讨论】:

  • 描述这些表。如果显式指定内部连接,是否会得到相同的结果?

标签: oracle natural-join


【解决方案1】:

我的建议是不要使用 NATURAL JOIN。明确定义您的连接条件以避免混淆和“隐藏的错误”。这是关于这个主题的official NATURAL JOIN Oracle documentationmore discussion

【讨论】:

  • 非常感谢!这帮助我诊断出我的错误 (gist.github.com/72614),结果证明这是由于 NATURAL JOIN。
【解决方案2】:

如果它完全按照你说的那样发生,那么它一定是一个优化器错误,你应该将它报告给 Oracle。

【解决方案3】:

你应该试试count(*)

两者是有区别的。
count(1) 表示计数行,其中 1 不为空
count(*) 表示计算行数

【讨论】:

  • 由于 1 永远不会为空,因此潜在结果没有差异。
  • ... 并且 count(1) 无论如何都会被重写为 count(*) 。 asktom.oracle.com/pls/asktom/…
【解决方案4】:

刚刚注意到您使用了 2 个自然连接... 从文档中,您只能在 2 个表上使用自然联接 Natural_Join

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2018-11-30
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多