我有表个用户:
user_id | lang_id
--------+---------
12345 | en
54321 | ru
77777 | uz
和表格文本:
text_id | en | ru | uz
--------+--------+---------+-------
hi | Hello! | Привет! | Salom!
bye | Bye! | Пока! | Xayr!
我有两个信息:
user_id = 12345
text_id ='hi'
并且我正在尝试查询,以获取用户所选语言的文本:
SELECT (SELECT lang_id FROM users WHERE user_id = 12345) FROM texts
WHERE text_id = 'hi'
并得到这个:
lang_id
------
en
我应该收到文本“ Hello!”
如果您能帮助我解决这个问题,那么我是PostgreSQL的新手吧:)
答案 0 :(得分:5)
虽然我100%建议将架构更改为适当的规范化,例如Jorge Campos在注释中提出的建议,但是您可以在CASE
语句中使用一些硬编码来获取文本。
SELECT
CASE
WHEN users.lang_id = 'en' THEN texts.en
WHEN users.lang_id = 'ru' THEN texts.ru
WHEN users.lang_id = 'uz' THEN texts.uz
END as user_language_text
FROM
users, texts
WHERE
user_id = 12345
AND text_id = 'hi';
这里有一些主要的缺点:
texts
中检索数据的哪一列,必须对可能的语言值进行硬编码。这意味着每次添加新语言时,不仅需要向表中添加新列(本身就是主要的反模式),还必须调整所有SQL来适应。 texts
与用户的lang_id
之间的关系。如果lang_id
是文本表中的一列,则您可以在其中联接,然后在texts
表中选择与用户的lang_id
相对应的值。 再次。我强烈建议您重新考虑您的架构,因为这将使您陷入无法扩展的噩梦,将导致您不断编辑架构以及SQL中的硬代码值。
答案 1 :(得分:4)
最简单的方法是将行强制转换为json,然后动态访问字段。它与您的原始查询非常相似:
select row_to_json(t.*)->(select lang_id
from users
where user_id = 12345)
from texts t
where text_id = 'hi'
答案 2 :(得分:1)
我认为开发本地化方法不正确。您可以制作表texts
其参数为text_id
,lang_id
和text
。它可以帮助开发更灵活的
您可以的话
SELECT
case
when u.user_id = 'en' then t.en
when u.user_id = 'ru' then t.ru
when u.user_id = 'uz' then t.uz
else t.en
end as text
FROM texts as t
left join lateral (
SELECT lang_id
FROM users
WHERE user_id = 12345
) as u on true
WHERE text_id = 'hi'