多语言数据库设计中的回退

Fallback in a multilingual database design

我正在设计一个关于产品的多语言数据库——多么新颖 ;)

这是简化的设计:

如果我select数据为'de',它是否为空(NULL):

select 
    p.id,
    p.price,
    pi.name,
    pi.description
from public.products p
inner join public.locales loc
on loc.lang = 'de'
left join public.products_i18n pi
on p.id = pi.id and pi.lang = loc.id

当所需的语言环境不存在时,我想退回到英语:

select 
    p.id,
    p.price,
    coalesce(pi.name, pi_def.name),
    coalesce(pi.description, pi_def.description)
from public.products p
inner join public.locales loc
on loc.lang = 'de'
left join public.products_i18n pi
on p.id = pi.id and pi.lang = loc.id
left join public.products_i18n pi_def
on p.id = pi_def.id and pi_def.lang = '1' -- fallback on english

但是,我收到两行:1 行具有正确的回退数据(描述应该是空的),1 行是空的。

是 pgAdmin 的显示问题还是我的查询有误?

SQL fiddle 可用: http://sqlfiddle.com/#!17/485be/1

无需加入2份public.products_i18n
过滤 public.locales 使其 returns 只有 'de''en' 并使用 FIRST_VALUE() window 函数获取 'de' 的详细信息或'en' 如果 'de' 不存在:

select distinct p.id, p.price,
       first_value(pi.name) over (partition by p.id order by loc.lang = 'de' desc) "name",
       first_value(pi.description) over (partition by p.id order by loc.lang = 'de' desc) description
from public.products p
inner join public.products_i18n pi on p.id = pi.id 
inner join public.locales loc on loc.lang in ('de', 'en') and pi.lang = loc.id;

参见demo