在SQL Select语句中提供语言FallBack

时间:2013-05-17 15:42:27

标签: sql sql-server tsql

我有一张代表Object的表格。它有许多列,但也有需要语言支持的字段。

为简单起见,我想说我有3个表:

  • MainObjectTable
  • LanguageDependantField1
  • LanguageDependantField2。

MainObjectTable有一个名为ID的PK int,两个LanguageDependantTables都有一个返回MainObjectTable的外键链接以及语言代码和添加日期

我创建了一个接受MainObjectTable ID和Language的存储过程。它将返回包含语言表中最新项的单行。 select语句看起来像

SELECT 
    MainObjectTable.VariousColumns, 
    LanguageDependantField1.Description, 
    LanguageDependantField2.SomeOtherText
FROM 
    MainObjectTable 
OUTER APPLY
     (SELECT TOP 1 LanguageDependantField1.Description
      FROM LanguageDependantField1
      WHERE LanguageDependantField1.MainObjectTable_ID = MainObjectTable.ID 
        AND LanguageDependantField1.Language_ID = @language
      ORDER BY 
         LanguageDependantField1.[Default], LanguageDependantField1.CreatedDate DESC) LanguageDependantField1
OUTER APPLY
     (SELECT TOP 1 LanguageDependantField2.SomeOtherText
      FROM LanguageDependantField2
      WHERE LanguageDependantField2.MainObjectTable_ID = MainObjectTable.ID 
        AND LanguageDependantField2.Language_ID = @language
      ORDER BY 
        LanguageDependantField2.[Default] DESC, LanguageDependantField2.CreatedDate DESC) LanguageDependantField2
WHERE 
     MainObjectTable.ID = @MainObjectTableID

我想要添加的是,如果找不到指定语言的行,则可以回退到默认语言。假设我们使用“德语”作为选定的语言。如果德语不存在,假设我们有LanguageDependantField1

,是否可以从@fallbackLanguageID返回英文行

我也是正确的在这种情况下使用OUTER APPLY或我应该使用JOIN吗?

非常感谢你的帮助。

2 个答案:

答案 0 :(得分:1)

试试这个:

  SELECT MainObjectTable.VariousColumns, 
        COALESCE(PrefLang.Description,Fallback.Description,'Not Found Desc') 
                 as Description,
        COALESCE(PrefLang.SomeOtherText,FallBack.SomeOtherText,'Not found') 
                 as SomeOtherText
    FROM MainObjectTable    
    LEFT JOIN 
        (SELECT TOP 1 pl.Description,pl.SomeOtherText
                  FROM LanguageDependantField1 pl
              WHERE pl.MainObjectTable_ID = MainObjectTable.ID 
                AND pl.Language_ID = @language
              ORDER BY 
                 pl.[Default], pl.CreatedDate DESC) 
    PrefLang ON 1=1
    LEFT JOIN 
        (SELECT TOP 1 fb.Description,fb.SomeOtherText
                  FROM LanguageDependantField1 fb
              WHERE fb.MainObjectTable_ID = MainObjectTable.ID 
                AND fb.Language_ID = @fallbackLanguageID
          ORDER BY 
                 fb.[Default], fb.CreatedDate DESC) 
    Fallback ON 1=1

    WHERE 
         MainObjectTable.ID = @MainObjectTableID

基本上,进行两个查询,一个是首选语言,另一个是英语(默认)。使用LEFT JOIN,如果找不到第一个,则使用第二个查询......

我没有您的实际表格,因此上面可能存在语法错误,但希望它能为您提供您想要尝试的概念...

答案 1 :(得分:0)

是的,如果要将Outer Apply表行与内部查询相关联,则MainObjectTable的使用是正确的。您不能将派生表中的引用使用连接到外部表。如果您想使用连接,则需要包含连接列,在这种情况下,预过滤结果。这可能是这样的:

With RankedLanguages As
    (
    Select LDF1.MainObjectTable_ID, LDF1.Language_ID, LDF1.Description, LDF1.SomeOtherText, ...
        , Row_Number() Over ( Partition By LDF1.MainObjectTable_ID, LDF1.Language_ID
                                Order By LDF1.[Default] Desc, LDF1.CreatedDate Desc ) As Rnk
    From LanguageDependantField1 As LDF1
    Where LDF1.Language_ID In( @languageId, @defaultLanguageId )
    )
Select M.VariousColumns
    ,  Coalesce( SpecificLDF.Description, DefaultLDF.Description ) As Description
    ,  Coalesce( SpecificLDF.SomeOtherText, DefaultLDF.SomeOtherText ) As SomeOtherText
    ,  ...
From MainObjectTable As M
    Left Join RankedLanguages As SpecificLDF
        On SpecificLDF.MainObjectTable_ID = M.ID
            And SpecifcLDF.Language_ID = @languageId
            And SpecifcLDF.Rnk = 1

    Left Join RankedLanguages As DefaultLDF
        On DefaultLDF.MainObjectTable_ID = M.ID
            And DefaultLDF.Language_ID = @defaultLanguageId
            And DefaultLDF.Rnk = 1

Where M.ID = @MainObjectTableID