如何获取默认语言的文本

gar*_*rik 6 sql-server-2008 query cte t-sql

我有这样的表: 在此处输入图片说明

因此语言表中的数据:

在此处输入图片说明

因此文本表中的数据: 在此处输入图片说明

我必须返回请求语言的文本(如果存在)默认语言的文本(如果它不存在)。是否可以在一个查询中做到这一点(不while,拜托)?

代码:

DECLARE @CommentId  bigint = 1
--DECLARE @LanguageCode  nvarchar(2) = 'en' -- "english text" returns
DECLARE @LanguageCode  nvarchar(2) = 'ua'   -- nothing at this moment

SELECT
     t.CommentId
    ,t.TextId
    ,t.[Text]
    ,t.LanguageId
    ,RequestedLanguageId = @LanguageCode
FROM dbo.common_Text t 
    INNER JOIN dbo.common_LanguageType l 
        ON t.LanguageId = l.LanguageId
WHERE l.Code = @LanguageCode 
    AND t.CommentId = @CommentId
Run Code Online (Sandbox Code Playgroud)

谢谢你。

添加:

如果代码请求“ua”(乌克兰语)文本,而这不是该语言的任何文本,那么它将搜索俄语文本。如果找到 - 好的,如果没有,它将寻找英文文本。语言列表可能会有所不同。

Nic*_*mas 6

使用递归 CTE,此查询构建一个包含所有语言的表,这些语言在其默认链中的某处指向具有所需注释的语言。它在具有所需注释的第一个默认语言旁边显示每种语言。然后过滤此表,为您提供所选语言的第一个可用文本。

DECLARE @CommentId BIGINT = 1;
DECLARE @LanguageCode NVARCHAR(2) = 'en';

WITH languages AS (
    -- base case: language has required comment
    SELECT 
          lt.LanguageId AS RootLanguageId
        , lt.LanguageId
        , lt.Code
        , lt.DefaultId
        , 0 AS Level
    FROM 
        dbo.common_LanguageType lt
    --WHERE
    --  lt.LanguageId = lt.DefaultId
    WHERE
        EXISTS (
            SELECT *
            FROM dbo.common_Text    t
            WHERE 
                    t.CommentId = @CommentId
                AND t.LanguageId = lt.LanguageId
        )

    UNION ALL

    -- recursive case: language is not its own default and
    --                 does not have the required comment
    SELECT
          l_default.RootLanguageId
        , l.LanguageId
        , l.Code
        , l.DefaultId
        , l_default.Level + 1 AS Level
    FROM
                    dbo.common_LanguageType l
        INNER JOIN  languages               l_default
            ON l.DefaultId = l_default.LanguageId
    WHERE
            l.LanguageId <> l.DefaultId
        AND NOT EXISTS (
            SELECT *
            FROM dbo.common_Text    t
            WHERE 
                    t.CommentId = @CommentId
                AND t.LanguageId = l.LanguageId
        )
)
SELECT t.Text
FROM 
                languages       l
    INNER JOIN  dbo.common_Text t
        ON  l.RootLanguageId = t.LanguageId
WHERE
    l.Code = @LanguageCode
;
Run Code Online (Sandbox Code Playgroud)

尝试运行

SELECT *
FROM languages;
Run Code Online (Sandbox Code Playgroud)

如果您想了解递归 CTE 正在做什么。我上传了一个脚本来创建表,插入一些示例数据,并运行上面的代码到 gist

很性感,不是吗?

  • 我已经测试过了。它有效并且它的工作速度再次提高了 45%,我的 55%。完美的!谢谢!我希望,你没有浪费时间!:) (2认同)