我有一个查询,我执行三个左外连接,但我只想返回一个结果。
我回答了这个问题: 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
我最初的想法是建立上述问题,但我无法在多个连接中进行比较,而无需为trm返回NULL值或返回对象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)
任何指导都将不胜感激。谢谢你的阅读!
更新:我没有制作这个数据库,也无法对其进行重组。
答案 0 :(得分: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;
这个稍微复杂的版本将保留“obj”表中的所有行,您需要这些行才能获得所需的结果集。
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”和“ord”两者的连接(或多个连接)中使用这些派生表中的任何一个。在下面的示例中,我在公用表表达式中使用第二个语句(上面),并在两个列上连接。
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表从根本上简化你的生活。直接引用“名称”和“trm”。 (我忽略了“lex”表,其目的简直莫名其妙。)
name trm ord
--
cat lion 3
cat puma 2
cat cgr 1
bear brn 1
根据目的,对于针对该表的某些查询,您可能不需要任何连接。
答案 1 :(得分: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
希望这有助于某人!