【问题标题】:SQL left join with case and limitied conditionsSQL left join with case and limited conditions
【发布时间】:2022-01-11 11:57:33
【问题描述】:

我想根据以下条件将翻译表左连接到表 1: 如果翻译表中有浏览器语言项,请选择此项。如果没有检查是否有操作系统语言的项目,如果没有则选择默认(空)语言。

表1

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

【问题讨论】:

  • WHERE 子句中使用t2 上的过滤器,使用LEFT JOIN 毫无意义 - 结果集中在t2 中没有匹配行的任何行都将被过滤掉WHERE 子句,因为 NULL 永远不等于任何东西。您是不是要将过滤器放在 JOIN 条件中?
  • 请编辑您的问题并为您的 RDBMS 添加正确的tag
  • 在 where/on 中使用 AND/OR 而不是 case 表达式通常会更好。

标签: sql join case


【解决方案1】:

您可以多次加入翻译表,每种语言一次;在 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 采用第一个非“空”的“文本”值。如果coalesce 函数不可用,则可以使用 case-when 来执行此操作。

【讨论】:

    【解决方案2】:

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

    例如,在 MS SQL Server 中:

    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
    ;
    

    【讨论】:

      猜你喜欢
      • 2021-06-11
      • 1970-01-01
      • 2021-06-14
      • 1970-01-01
      • 2010-12-13
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多