我有这样一张桌子
TABLE_ITEM_DEFINITION
:
╔═════════════════════╦══════════╦═══════════╗
║ Name ║ Language ║ object_id ║
╠═════════════════════╬══════════╬═══════════╣
║ My Name in english ║ en ║ 123459098 ║
║ mon nom en espagnol ║ sp ║ 123459098 ║
║ my name in Klingon ║ kl ║ 123459098 ║
╚═════════════════════╩══════════╩═══════════╝
在我的查询后显示对象时:我打算获取英文名称(如果存在),否则如果存在则为西班牙语,否则为klingon..I.E。我只会显示一个首先符合我标准的名称。
答案 0 :(得分:1)
您可以使用COALESCE
并自行加入:
SELECT m.*, COALESCE(t1.Name, t2.Name, t3.Name) AS result
FROM MAIN_OBJECT_TABLE m
LEFT JOIN TABLE_ITEM_DEFINITION t1
ON m.object_id = t1.object_id
AND t1.Language = 'en'
LEFT JOIN TABLE_ITEM_DEFINITION t2
ON m.object_id = t2.object_id
AND t2.Language = 'sp'
LEFT JOIN TABLE_ITEM_DEFINITION t3
ON m.object_id = t3.object_id
AND t3.Language = 'kl'
WHERE m.object_id = 123459098;
的 LiveDemo
强>
答案 1 :(得分:1)
我认为在这种情况下,最好的方法是先改进你的设计。由于您有许多具有不同语言名称的对象,因此您应该为语言优先级创建一个表:
create table language_priority (
language_name varchar2(2),
priority_level number);
insert into language_priority(language_name, priority_level) values ('en', 1);
insert into language_priority(language_name, priority_level) values ('sp', 2);
insert into language_priority(language_name, priority_level) values ('kl', 3);
现在您使用TABLE_ITEM_DEFINITION
加入此表并选择具有最高优先级的行:
select name
from (select name, row_number() over (order by lp.priority_level) rn
from TABLE_ITEM_DEFINITION tid,
language_priority lp
where lp.language_name = tid.language
and tid.object_id = 123459098)
where rn = 1
您还可以制作"优先级表"没有创建表,使用with
子句,但这个解决方案是一种硬编码:
with language_priority as (
select 'en' language_name, 1 priority_level union all
select 'sp' language_name, 2 priority_level union all
select 'kl' language_name, 3 priority_level)
select name
from (select name, row_number() over (order by lp.priority_level) rn
from TABLE_ITEM_DEFINITION tid,
language_priority lp
where lp.language_name = tid.language
and tid.object_id = 123459098)
where rn = 1
这两种解决方案都可以轻松添加许多新语言并改变其优先级。
答案 2 :(得分:0)
select name, object_id, language
from (
select name, object_id, language,
row_number() over (order by decode(language, 'en', 1, 'sp', 2, 3) as rn
from table_item_definition
where object_id = 123459098
) t
where rn = 1;
如果您需要将其加入main_object_table
表,您可以这样做:
select m.*,
ti.name,
ti.language
from main_object_table m
join (
select name, object_id, language,
row_number() over (partition by object_id order by decode(language, 'en', 1, 'sp', 2, 3) as rn
from table_item_definition
) ti on ti.object_id = m.object_id and ti.rn = 1
where m.object_id = 123459098;
如果table_item_definition
中根本没有行,那么您需要使用外部联接(left join
)而不是内部联接。
答案 3 :(得分:0)
作为替代方案:
select UNIQUE object_id,
FIRST_VALUE(Name) OVER (PARTITION BY object_id
ORDER BY (case when Language = 'en' then 1
when Language = 'sp' then 2
else 3 end))
from TABLE_ITEM_DEFINITION