這裏是設置 -這是一種可接受的加入方式(左外連接表)嗎?
create table tasks (taskno int, customerno int);
insert into tasks values (1, 100);
commit;
insert into tasks values (2, 200);
commit;
insert into tasks values (3, 300);
commit;
select * from tasks;
create table items (taskno int, accountno int);
commit;
insert into items values (1, 1000);
commit;
insert into items values (2, 2000);
commit;
select * from items;
create table accounts (accountno int, customerno int);
commit;
insert into accounts values (1000, 100);
commit;
insert into accounts values (1100, 100);
commit;
insert into accounts values (2000, 200);
commit;
insert into accounts values (3000, 300);
commit;
select * from accounts;
我想基於一個accountno從任務表中的taskno。任務表只有一個叫做customerno的東西。此customerno可以與多個accountno關聯(將customerno視爲父母,並將accountno視爲小孩)。所以,如果你看看我們的設置,如果我通過在accountno 1000或者1100都將在該查詢返回taskno 1 -
select a.taskno
from tasks a, accounts c
where a.customerno = c.customerno
and c.accountno = 1000 -- but will return taskno 1 also for 1100
我想要一些更精細的細節莫過於此。所以我發現了另一個表'Items',它有taskno和accountno。所以,如果我把它添加到查詢,它會返回正確的taskno 1 accountno 1000而不是1100
select a.taskno
from tasks a, items b, accounts c
where a.taskno = b.taskno
and a.customerno = c.customerno
and c.accountno = b.accountno
and c.accountno = 1000 -- nothing returned for 1100
這是一切都很好,但項目表並不總是可靠的。它可以說只有在任務表中找到的任務的90%。所以當任務未在項目表中發現這種情況下,我想從任務表,像accountno 3000(這意味着我將不得不customerno去,不會有accountno的粒度級別加入。但它是確定) 。但是當在這個項目中找到這個accountno時,我希望它被使用,因爲它有accountno,這給了我沒有與確切accountno關聯的taskno。因此,我將左外部聯接用於包含任務的項目。
這工作perfectly-
select a.taskno
from tasks a, items b, accounts c
where a.taskno = b.taskno(+)
and a.customerno = c.customerno
and c.accountno = nvl(b.accountno, c.accountno)
and c.accountno = 3000 -- will return taskno 3
select a.taskno
from tasks a, items b, accounts c
where a.taskno = b.taskno(+)
and a.customerno = c.customerno
and c.accountno = nvl(b.accountno, c.accountno)
and c.accountno = 1000 --returns 1 and nothing returned for 1100
我的問題是我有構造正確的查詢這裏 - 特別是我在哪裏聯用NVL項目以帳戶的一部分?這是預期的方式嗎?或者這是一個奇怪的回合嗎?
好,你將會在這裏告訴你的第一件事是:使用ANSI連接語法! – sstan
即使Oracle建議停止使用專有的'(+)'在where子句中使用隱式外連接,並使用明確的'LEFT JOIN'(或'RIGHT JOIN')運算符。 –
我不明白你爲什麼要加入'items'表,如果你只從'tasks'表中進行選擇,並且通過'accounts'表字段進行過濾,並且兩個表都可以連接。爲什麼你需要在查詢中包含'items'?除非你也從'items'中選擇信息,但是你沒有顯示。 – sstan