我有表用户:
user_id | lang_id
--------+---------
12345 | en
54321 | ru
77777 | uz
以及表格文本:
text_id | en | ru | uz
--------+--------+---------+-------
hi | Hello! | Привет! | Salom!
bye | Bye! | Пока! | Xayr!
我有两个信息:
用户id=12345
文本id='嗨'
我正在尝试此查询,以获取用户所选语言的文本:
SELECT (SELECT lang_id FROM users WHERE user_id = 12345) FROM texts
WHERE text_id = 'hi'
得到这个:
lang_id
------
en
我应该收到短信“你好!”
我是PostgreSQL的新手,如果你能帮我解决这个问题,我会很好的:)
最佳答案
虽然我百分之百地建议将模式更改为像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的角度来看,CASE语句代价很高
要确定从
texts
中检索数据的列,必须硬编码可能的语言值。这意味着每次添加新语言时,不仅要向表中添加新列(主要的反模式本身),而且还必须调整所有的SQL以适应。必须交叉联接(或不带相关性的子查询)才能导出
texts
与用户的lang_id
之间的关系。如果lang_id
是文本表中的一列,则可以加入其中,只需在texts
表中选取与用户的lang_id
相对应的值。再一次。我强烈建议您重新考虑您的模式,因为这将使您走向一个无法扩展的噩梦,这将导致您不断地编辑您的模式和SQL中的硬代码值。