Frage

Ich habe so Tische:enter image description here

und so Daten in der Sprache Tabelle:

enter image description here

und so Daten in der Texttabelle:enter image description here

Ich muss Text für zurückgeben angefordert Sprache, wenn es existiert und Text für Ursprünglich Sprache, wenn es tut nicht existieren. Ist es möglich, das in zu tun? eines Abfrage (Nr while, bitte)?

Code:

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

Vielen Dank.

HINZUGEFÜGT:

Wenn Code einen Text in 'ua' (ukrainisch) anfordert und dies kein Text für diese Sprache ist, wird er den Text nach Russisch suchen. Wenn gefunden - ok, wenn es nicht nach einem Text für Englisch sucht. Die Liste der Sprachen kann variieren.

War es hilfreich?

Lösung

Mit einem rekursiven CTE erstellt diese Abfrage eine Tabelle aller Sprachen, die irgendwo in ihrer Standardkette auf eine Sprache zeigen, die den erforderlichen Kommentar enthält. Es zeigt jede Sprache neben ihrem ersten Standard, der den erforderlichen Kommentar enthält. Anschließend filtert diese Tabelle, um Ihnen den ersten verfügbaren Text für die von Ihnen ausgewählte Sprache zu geben.

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
;

Versuchen Sie einfach zu rennen

SELECT *
FROM languages;

Wenn Sie ein Gefühl für das bekommen möchten, was der rekursive CTE tut. Ich habe ein Skript hochgeladen, um die Tabellen zu erstellen, einige Beispieldaten einzufügen und den obigen Code auszuführen zu gist.

Ziemlich sexy, nein?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top