1

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

为简单起见,假设我有 3 个表:

  • 主对象表
  • LanguageDependantField1
  • LanguageDependantField2。

MainObjectTable有一个名为 的 PK int ID,并且两者LanguageDependantTables都有一个指向 的外键链接MainObjectTable以及语言代码和添加日期。

我创建了一个接受 MainObjectTable ID 和Language. 它将返回包含语言表中最新项目的单行。选择语句看起来像

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

非常感谢您的帮助。

4

2 回答 2

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,所以如果没有找到第一个查询,则使用第二个查询...

我没有你的实际表格,所以上面可能有语法错误,但希望它能给你想要尝试的概念......

于 2013-05-17T17:07:40.970 回答
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     
于 2013-05-17T18:58:09.593 回答