我有表用户
user_id | lang_id
--------+---------
12345 | en
54321 | ru
77777 | uz
和表格texts
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
我应该得到的文本是“
!”
我是PostgreSQL的新手,如果你能帮我解决这个问题,那就更好了:)
发布于 2018-07-25 03:53:51
虽然我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';
不过,这也有一些主要的缺点:
从CPU的角度来看,
texts
中的哪一列检索数据,必须对可能的语言值进行硬编码。这意味着每次添加一种新语言时,不仅必须向表中添加新列(主要的反模式本身),还必须调整所有SQL以适应需要。texts
和用户的lang_id
之间的关系。如果lang_id
是文本表中的一列,那么您将连接到那里,并在texts
表中选取与用户的lang_id
相对应的值。再来一次。我强烈建议您重新考虑您的模式,因为这将使您走向无法扩展的噩梦,并导致您不断地编辑您的模式,并在SQL中硬编码值。
发布于 2018-07-25 04:10:05
最简单的方法是将row转换为json,然后动态访问字段。它与您的原始查询非常相似:
select row_to_json(t.*)->(select lang_id
from users
where user_id = 12345)
from texts t
where text_id = 'hi'
发布于 2018-07-25 03:54:27
在我看来,开发本地化是不正确的方法。您可以使用参数text_id
、lang_id
和text
制作表texts
。并且它可以帮助开发出更灵活的
在你的情况下,你可以做到
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'
https://stackoverflow.com/questions/51506336
复制相似问题