2014-03-07 137 views
0

我有一個查詢,我執行三個左外連接,但我只想返回一個結果。多外連接返回一個結果

我問這個問題一段時間回來: Multiple Outer joins return top result

添加到的是,我無法回到最上面一行是若干個連接的路程。

例如:

obj 

|id | name | 
1  | bear | 
2  | cat | 
3  | moose | 


obj_cn 

|id | obj_id | lex_id | ord 
| 1 | 2  | 1  | 3 
| 2 | 2  | 2  | 2 
| 3 | 2  | 3  | 1 
| 4 | 1  | 4  | 1 

lex 

| id | trm_id | 
| 1 | 2  | 
| 2 | 1  | 
| 3 | 4  | 
| 4 | 3  | 

trm 

| id | trm | 
| 1 | puma| 
| 2 | lion| 
| 3 | brn | 
| 4 | cgr| 

理想情況下,我想在objtermktr表返回有序的最低期限,與其他列一起(和其它連接,這個例子是簡化)。

results 

|id | name | trm 
|1  | bear | brn 
|2  | cat | cgr 
|3  | moose | NULL 

我最初的想法是建立過上述問題的,但我有比較多個連接沒有任何返回NULL值TRM或返回對象ID 2三次(每次一個學期)的麻煩。

此查詢不工作,但這裏是那種我試圖

SELECT id, name , 
,(select trm from trm t where t.id = a.id and r.ord=a.ord7) as term 
from obj 

left outer join 
(select obj_id, lex_id, MIN(ord) ord7 from obj_cn group by obj_id, lex_id) a 
on obj.id = a.obj_id 

left outer join lex on a.lex_id = lex.trm_id 
left outer join trm on lex.trm_id = trm.id) 

任何指導,將不勝感激。謝謝閱讀!

更新:我沒有製作這個數據庫,也無法重構它。

回答

1

如果包含CREATE TABLE和INSERT語句,它會有很大幫助。

create table obj (
    id integer primary key, 
    name varchar(10) not null unique 
); 

insert into obj values 
(1, 'bear'), 
(2, 'cat'), 
(3, 'moose'); 

create table trm (
    id integer primary key, 
    trm varchar(10) not null unique 
); 

insert into trm values 
(1, 'puma'), 
(2, 'lion'), 
(3, 'brn'), 
(4, 'cgr'); 

create table lex (
    id integer primary key, 
    trm_id integer not null 
    references trm (id) 
); 

insert into lex values 
(1, 2), 
(2, 1), 
(3, 4), 
(4, 3); 

create table obj_cn (
    id integer primary key, 
    obj_id integer not null 
    references obj (id), 
    lex_id integer not null 
    references lex (id), 
    ord integer not null 
    check (ord > 0), 
    unique (obj_id, lex_id) 
); 

insert into obj_cn values 
(1, 2, 1, 3), 
(2, 2, 2, 2), 
(3, 2, 3, 1), 
(4, 1, 4, 1); 

理想情況下,我想在objtermktr表與其他 列返回訂購的最低期限,沿(和其它連接,這個例子 是簡化)。

聽起來像這樣給你最低有序的術語。

select obj_id, min(ord) as ord 
from obj_cn 
group by obj_id; 

這個稍微複雜的版本將在「目標文件」表,你需要爲了得到你想要的結果集保存所有行。

select obj.id as obj_id, min(ord) as ord 
from obj 
left join obj_cn on obj.id = obj_cn.obj_id 
group by obj.id 

你可以在「obj_id」或兩個「obj_id」和「奧德」請使用這些派生表的一個連接(或多個連接)。在下面的例子中,我使用公共表格表達式中的第二個語句(上面),並在兩個列上連接。

with min_ords as (
    select obj.id as obj_id, min(ord) as ord 
    from obj 
    left join obj_cn on obj.id = obj_cn.obj_id 
    group by obj.id 
) 
select obj.id, obj.name, trm.trm 
from obj 
left join min_ords on min_ords.obj_id = obj.id 
left join obj_cn on obj_cn.obj_id = obj.id and obj_cn.ord = min_ords.ord 
left join lex on lex.id = obj_cn.lex_id 
left join trm on trm.id = lex.trm_id 
order by id 

1 bear brn 
2 cat cgr 
3 moose 

既然你肯定有obj.name和trm.trm唯一約束,可以從根本上通過重組obj_cn表簡化你的生活。直接引用「name」和「trm」。 (我忽略了「法」的表,其目的是簡直莫名其妙。)

name trm ord 
-- 
cat lion 3 
cat puma 2 
cat cgr 1 
bear brn 1 

根據不同的目的,你可能不需要任何加入一些查詢爲目標的表。

+0

謝謝,我明白你的意思是關於莫名其妙的結構。然而,我沒有重建數據庫的奢侈,只是從數據庫中獲取數據的樂趣。 – user2856332

+0

@ user2856332:已添加到答案。 –

+0

嗯,我甚至沒有考慮派生表。謝謝你的幫助。 – user2856332

0

Arg,我把連接放在錯誤的地方。仍然在學...

select obj.id, obj.name, 
(select trm.trm from obj_cn F 
left outer join lex on f.lex_id = lex.id 
left outer join trm on lex.trm_id = trm.id 
where f.obj_id=C.obj_id and f.ord=C.ord7) 

from obj 

left outer join (select obj_id, MIN(ord) ord7 from obj_cn group by obj_id) C 
on obj.id = C.obj_id 

希望這可以幫助別人!