SQL - 当翻译不存在时回退到默认语言

问题描述 投票:0回答:3

在表(tbl_i18n)中记录不同语言的文本,其结构如下:

text_FK | language_FK | value
-----------------------------
    1   |       1     | hello
    1   |       2     | hallo
    2   |       1     | world
    3   |       1     | test

通过简单的连接给出特定语言(id = 2)的文本:

SELECT [value] FROM tbl_i18n i
   JOIN tbl_products p ON p.text_id = i.text_FK
   JOIN tbl_languages l ON l.id = i.language_FK AND i.language FK = 2;

结果是:

 value
-------
 hallo

如何更改上述 select 语句,以便我们可以获得默认语言,并且当文本字段的翻译不存在时,将显示其后备文本,结果将变为:

 value
-------
 hallo
 world
 test
sql sql-server internationalization
3个回答
2
投票

LEFT JOIN
语言表两次。第一次用于所需语言,第二次用于后备值。使用
COALESCE
选择所需语言(如果可用),否则选择后备语言。

SELECT coalesce(l1.[value], l2.[value])
FROM tbl_i18n i
JOIN tbl_products p ON p.text_id = i.text_FK
LEFT JOIN tbl_languages l1 ON l.id = i.language_FK AND i.language_FK = 2
LEFT JOIN tbl_languages l2 ON l.id = i.language_FK AND i.language_FK = 1;

1
投票

我想用简单的英语来说,你想要每个

language_FK
的最高可用
text_FK

WITH X AS (
SELECT *
     ,ROW_NUMBER() OVER (PARTITION BY text_FK ORDER BY language_FK DESC)rn
FROM TableName 
)
SELECT *
FROM X
WHERE X.rn = 1

0
投票

让我们举一个更难的例子: 我有一个 post_translations 表,其中包含每个语言环境的帖子的所有翻译,语言环境是一个字符串,post_id 是帖子的 id。

我们想要选择所有“it”帖子并回退到“en”。

SELECT * FROM 
(
SELECT post_translations.* ,ROW_NUMBER() OVER (PARTITION BY post_id ORDER BY (CASE locale WHEN 'it' then 1 WHEN 'en' THEN 2 ELSE 3 END)) AS tr_rank 
FROM post_translations
) ranked_post_translations
WHERE tr_rank=1

我们将从子查询中选择所有帖子,该子查询将以升序排列我们的翻译(1 是首选翻译);我们将在按首选翻译排序的分区上使用 ROW_NUMBER 来计算“翻译排名”(我们将使用 CASE,因为我们无法按语言环境字符串排序)。

只需将多种后备语言添加到 CASE 语句中即可轻松扩展该脚本(例如 it=1、en=2、de=3、es=4 等)

© www.soinside.com 2019 - 2024. All rights reserved.