Domanda

Ho così le tabelle: entrare descrizione dell'immagine qui

e così i dati in tabella Lingua:

entrare descrizione dell'immagine qui

e così i dati al tavolo di testo: entrare descrizione dell'immagine qui

devo tornare di testo per richiesta lingua, se esiste e il testo per default lingua, se lo fa non esiste . E 'possibile farlo in una query (senza while, per favore)?

Codice:

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

Grazie.

AGGIUNTO:

Se il codice richiede un testo in 'ua' (ucraino) e questo non è un qualsiasi testo per questa lingua, in modo da sta andando a cercare il testo per il russo. se trovato - ok, se non cercherà un testo per l'inglese. Elenco delle lingue può variare.

È stato utile?

Soluzione

Utilizzando un CTE ricorsiva, questa query costruisce una tabella di tutte le lingue quel punto da qualche parte nella loro catena di default ad una lingua che ha il commento desiderato. Essa mostra ogni lingua vicino alla sua prima di default che ha il commento desiderato. E poi filtra questa tabella di darvi il primo testo disponibile per la lingua selezionata.

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
;

Prova solo in esecuzione

SELECT *
FROM languages;

se si vuole avere un'idea di ciò che il CTE ricorsiva sta facendo. Ho caricato uno script per creare le tabelle, inserire alcuni dati di esempio, ed eseguire il codice di cui sopra a Gist .

abbastanza sexy, no?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top