多语言数据库设计中的回退
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。
我正在设计一个关于产品的多语言数据库——多么新颖 ;)
这是简化的设计:
如果我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。