我有表用户:

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中的硬代码值。

10-08 16:16