我一直试图在数据库中使用语言一段时间,但这个让我感到难过。
所以这是两个表的简化结构
DATA
descID | descOriginal | deptID | Other Data
-----------|--------------|------- |-----------
10 | TshirtsNL | 1 | ...
20 | TrousersNL | 1 | ...
30 | ShoesNL | 1 | ...
和
LANG
descID |descTranslated| langID
-----------|--------------|-------
10 | TshirtsDE | 1
10 | TshirtsFR | 2
10 | TshirtsEN | 3
基本上,原始描述位于第一个表中,以及其他所需数据。但是,翻译的描述位于另一个表格中,用于何时需要翻译原始描述。
使事情进一步复杂化:并非所有LANG表中的行都已填充以与DATA表中的数据相对应(这仅在客户填写其翻译时发生)。这意味着我不能依赖简单的JOIN WHERE l.descID = d.descID
。
我一直在尝试不同类型的连接和合并,但我似乎无法使它工作。
我的Firebird版本(1.5)不支持以下版本,但如果您的数据库支持派生表,则可能会有效。
我认为这样的事情可行:
SELECT COALESCE(lang.descTranslated, data.descOriginal) AS desc
FROM
(SELECT descID, descOriginal FROM data WHERE deptID =
:deptID) data
LEFT JOIN
(SELECT descID, descTranslated FROM lang) lang
ON
data.descID = lang.descID
但Firebird似乎不喜欢这些语句(或者我遗漏了一些东西),因为以下测试SQL会抛出错误“unknown token SELECT”
SELECT * FROM (SELECT descID FROM data)
答案 0 :(得分:1)
正如Val Marinov已经评论过的,派生表是在Firebird 2.0中引入的(2006年)。但是,对于您的问题,您不需要使用派生表:
获得您想要的结果:
char
就足够了。如果要指定特定语言,则使用以下内容就足够了:
select coalesce(lang.desctranslated, data.descoriginal)
from data
left join lang
on data.descid = lang.descid
或将条件下推到联接:
select coalesce(lang.desctranslated, data.descoriginal)
from data
left join lang
on data.descid = lang.descid
where lang.langid = 2 or lang.langid is null
我已经使用Firebird 1.5.6和您问题的样本数据进行了测试。
答案 1 :(得分:1)
虽然Firebird 1.x不支持匿名派生表,但它支持视图。
CREATE VIEW DEPT_DESCS AS
SELECT lang.descID, lang.descTranslated as Dept_Description, lang.langID, languages.lang_name
FROM lang
LEFT JOIN DATA ON DATA.descID = lang.descID
JOIN languages ON languages.lang_id = lang.langID
WHERE DATA.descID is not null -- would not need translations for non-existing lines
ORDER BY lang.descID, lang.langID DESC
UNION ALL
SELECT data.descID, data.descOriginal, NULL, NULL FROM data
现在您可以从该视图中进行选择
SELECT first(1) * FROM DEPT_DESCS
WHERE ( langID in (5,8,10) or langID is NULL )
AND descID=10
ORDER by langID /* DESC */ NULLS LAST
请参阅https://www.firebirdsql.org/manual/nullguide-sorts.html
对于非翻译的描述,也可以使用零或负数而不是空。
CREATE VIEW DEPT_DESCS AS
SELECT lang.descID, lang.descTranslated as Dept_Description, lang.langID, languages.lang_name
.....
ORDER BY lang.descID, lang.langID DESC
UNION ALL
SELECT data.descID, data.descOriginal, -100 /* or 0 */, NULL FROM data
这样第二个查询变得更简单了。
SELECT first(1) * FROM DEPT_DESCS
WHERE langID in (5,8,10, -100 /* or 0 */ )
AND descID=10
ORDER by langID DESC
然而,使用magic constants
显然会要求