4

有谁知道为什么在 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 时,它就成了问题。

4

4 回答 4

9

My advice would be to NOT use NATURAL JOIN. Explicitly define your join conditions to avoid confusion and "hidden bugs". Here is the official NATURAL JOIN Oracle documentation and more discussion about this subject.

于 2008-09-19T17:34:52.977 回答
2

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

于 2008-09-19T16:28:44.477 回答
1

您应该尝试计数(*)

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

于 2008-09-19T16:31:26.687 回答
1

Just noticed you used 2 natural joins... From the documentation you can only use a natural join on 2 tables Natural_Join

于 2008-09-19T17:12:33.623 回答