SQL left join with case and limitied conditions

SQL left join with case and limitied conditions

我想根据以下条件将翻译 table 加入 table1: 如果翻译中有针对浏览器语言的项目table,请选择此项。如果没有,请检查是否有操作系统语言项,如果没有,请选择默认(空)语言。

table1

id item
0 tax
1 fee

翻译

id item language text
0 tax NULL Steuer
1 tax de Steuer
2 tax en tax
3 fee NULL Gebühr
4 fee de Gebühr
5 fee en charge
SELECT * FROM table1 t1
LEFT JOIN translation t2 ON t1.item = t2.item; 

会给我所有项目,例如:

结果

id item id item language text
0 tax 3 tax NULL Gebühr
0 tax 4 tax de Gebühr
0 tax 5 tax en charge
1 fee 0 fee NULL Steuer
1 fee 1 fee de Steuer
1 fee 2 fee en tax

我的方法是使用 CASE 但查询:

DECLARE @uiLanguage VARCHAR(2) = 'en';
DECLARE @osLanguage VARCHAR(2) = 'de';

    SELECT
        *
    FROM
        item t1
        LEFT JOIN translation t2 ON t1.item = t2.item
    WHERE
        t2.language = (CASE
            WHEN t2.language = @uiLanguage THEN @uiLanguage
           ELSE @osLanguage
        END);

给我这个结果:

结果

id item id item language text
0 tax 4 tax de Gebühr
0 tax 5 tax en charge
1 fee 1 fee de Steuer
1 fee 2 fee en tax

这是应该的或需要的:

结果

id item id item language text
0 tax 5 tax en charge
1 fee 2 fee en tax

我怀疑您需要使用相关子查询。

例如,在 MS SQL 服务器中:

DECLARE @uiLanguage VARCHAR(2) = 'en';
DECLARE @osLanguage VARCHAR(2) = 'de';

SELECT
    id,
    IsNull(t2.text, t1.text) text
FROM
    item t1
    OUTER APPLY
    (
        SELECT TOP 1 text
        FROM translation t2
        WHERE t2.item = t1.item
        AND t2.language IN (@uiLanguage, @osLanguage)
        ORDER BY CASE t2.language WHEN @uiLanguage THEN 0 ELSE 1 END
    ) t2
;

您可以通过多次加入翻译 table 来完成,每种语言一次;在 SQLServer 中:

DECLARE @uiLanguage VARCHAR(2) = 'en';
DECLARE @osLanguage VARCHAR(2) = 'de';

    SELECT
        t1.*,
        coalesce(t2_bl.text, t2_ol.text, t2_nl.text) as text
    FROM
        item t1
        LEFT JOIN translation t2_bl ON t1.item = t2_bl.item AND t2_bl.language = @uiLanguage
        LEFT JOIN translation t2_ol ON t1.item = t2_ol.item AND t2_ol.language = @osLanguage
        LEFT JOIN translation t2_nl ON t1.item = t2_nl.item and t2_nl.language is NULL
;

coalesce 取第一个 'text' 不是 'null' 的值。这可以通过 case-when if coalesce 函数不可用来执行。