我有一张代表Object
的表格。它有许多列,但也有需要语言支持的字段。
为简单起见,我想说我有3个表:
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
吗?
非常感谢你的帮助。
答案 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