2008-09-19 3 views
4

Кто-нибудь знает, почему в Oracle 11g, когда вы делаете граф (1) с более чем одним естественным соединением, он делает декартовое соединение и выбрасывает счет?Oracle Natural Joins and Count (1)

Такие, как

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

Это тянет назад, как 3 миллиона строк, когда

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, это стало проблемой.

+0

Опишите эти таблицы. Получаются ли те же результаты, если вы явно указываете внутреннее соединение? – Apocalisp 2008-09-19 16:27:52

ответ

9

Мой совет: НЕ использовать ПРИРОДНЫЙ СОЕДИНЕНИЕ. Четко определите условия соединения, чтобы избежать путаницы и «скрытых ошибок». Вот official NATURAL JOIN Oracle documentation и more discussion по этому вопросу.

1

Если это так, как вы говорите, то должен быть быть ошибкой оптимизатора, вы должны сообщить об этом Oracle.

1

вы должны попробовать COUNT (*)

Там есть разница между ними.
счетчик (1) означает, подсчета строк, где 1 не равно нулю
Количество (*) означает, подсчитывать строки

+1

Поскольку 1 никогда не является нулевым, нет никакой разницы в потенциальных результатах. – 2008-09-22 09:24:03

+2

... и count (1) переписывается, чтобы считать (*) в любом случае. http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1156159920245 – 2009-03-29 00:35:35

1

Просто заметил, что вы использовали 2 естественные соединения ... Из документации можно использовать только естественное соединение на 2 таблицы Natural_Join

+0

Это неверно (и сайт, на который вы ссылаетесь, не является документацией, это независимая Wiki): См. Http://68.142.116.68/docs/cd/B19306_01/server.102/b14200/statements_10002.htm#sthref9834 – 2008-09-22 09:22:21