私はそうテーブルを持っています:
言語テーブルのデータ:
テキストテーブルのデータ:
要求された言語のテキストを返す必要があります存在する場合およびdefault存在する場合の言語存在しない。 oneクエリ(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
ありがとうございました。
追加:
コードが 'ua'(ウクライナ語)のテキストを要求し、これがこの言語のテキストではない場合、ロシア語のテキストを検索します。見つかった場合-わかりました。見つからない場合は、英語のテキストが検索されます。言語のリストは異なる場合があります。
このクエリは、再帰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
;
走ってみて
SELECT *
FROM languages;
再帰的なCTEが何をしているかを感じたい場合。テーブルを作成し、いくつかのサンプルデータを挿入し、上記のコード to Gist を実行するスクリプトをアップロードしました。
かなりセクシーですね