T-SQL, где утверждение - ИЛИ - PullRequest
2 голосов
/ 20 апреля 2010

Извините за смутное название, но я действительно не знал, какое название дать этой проблеме:

У меня есть следующий набор результатов:

ID   Field   FieldValue   Culture
1    Color   Groen        nl-NL
2    Taste   Kip          nl-NL
3    Color   Green        en-GB
4    Taste   Chicken      en-GB
5    Color   Green        en
6    Taste   Chicken      en

Я хотел бы имитировать способ выбора ресурса ASP.Net, пользовательскую культуру (nl-NL)

SELECT Field, FieldValue FROM Tbl WHERE Culture = 'nl-NL'

Или, если нет результатов для конкретной культуры, попробуйте родительскую культуру (nl)

SELECT Field, FieldValue FROM Tbl WHERE Culture = 'nl'

Или, если нет результатов для родительской культуры, попробуйте стандартную культуру (en)

SELECT Field, FieldValue FROM Tbl WHERE Culture = 'en'

Как я могу объединить эти операторы SELECT в один оператор T-SQL?
Я использую LINQ, чтобы выражение LINQ было еще больше.

Оператор OR не сработает, потому что я не хочу смешивать разные культуры.
Оператор ORDER BY не поможет, потому что он возвращает несколько записей для каждой культуры.

Вывод может выглядеть следующим образом (nl-NL):

Color   Groen
Taste   Kip

или (en-GB / en):

Color   Green
Taste   Chicken

Ответы [ 5 ]

4 голосов
/ 20 апреля 2010

Итак, вот код, который делает именно то, что написано в вашем примере. Ожидается, что вы определите конкретную культуру (nl-NL), нейтральную культуру (nl) и резервную культуру (en) в коде на стороне клиента и передадите эти значения в SQL.

SELECT Field, FieldValue FROM Tbl WHERE Culture = (
    SELECT TOP 1 Culture FROM (
        SELECT 1 as n, Culture FROM Tbl WHERE Culture = 'nl-NL'
        UNION
        SELECT 2, Culture FROM Tbl WHERE Culture = 'nl'
        UNION
        SELECT 3, Culture FROM Tbl WHERE Culture = 'en'
    ) cultures
    ORDER BY n
)

Вы уверены, что вам нужна вся таблица перевода для данной культуры, а не перевод каждой строки? Что если у вас есть строки A и B в en, но только строка A в nl-NL?

2 голосов
/ 20 апреля 2010

Попробуйте это:

SELECT Field, FieldValue FROM Tbl WHERE Culture = 'nl-NL' 

union

SELECT Field, FieldValue FROM Tbl WHERE Culture = 'nl' 
and not exists(select * from tbl where culture = 'nl-NL')

union

SELECT Field, FieldValue FROM Tbl WHERE Culture = 'en' 
and not exists(select * from tbl where culture = 'nl-NL')
and not exists(select * from tbl where culture = 'nl')

Linq:

var x = (from a in tbl
        where culture == "nl-NL"
        select a
        )

        .Union

        (from a in tbl
        where culture == "nl"
        && !tbl.Any(c => c.Culture == "nl-NL")
        select a
        )

        .Union
        (from a in tbl
        where culture == "en"
        && !tbl.Any(c => c.Culture == "nl-NL")
        && !tbl.Any(c => c.Culture == "nl")
        select a
        );
1 голос
/ 20 апреля 2010

Предположим, что культура передается в @Culture:

select Field,COALESCE(fc.FieldValue,pc.FieldValue,dc.FieldValue)
from
    Tbl dc
        left join
    Tbl pc
        on
            dc.Field = pc.Field and
            pc.Culture = SUBSTRING(@Culture,1,CHARINDEX('-',@Culture)-1)
        left join
    Tbl fc
        on
            dc.Field = fc.Field and
            fc.Culture = @Culture
where
    dc.Culture = 'en'

вернет всю таблицу (псевдонимы могут быть длиннее - dc = культура по умолчанию, pc = частичная культура, fc = полная культура.

0 голосов
/ 20 апреля 2010

Другой метод;

SELECT * FROM tbl WHERE tbl.Culture = (
 SELECT COALESCE(
  CASE WHEN EXISTS (SELECT 1 FROM tbl WHERE Culture = @locale) THEN @locale ELSE NULL END,
  CASE WHEN EXISTS (SELECT 1 FROM tbl WHERE Culture = SUBSTRING(@locale, 1, CHARINDEX('-', @locale + '-') - 1)) THEN SUBSTRING(@locale, 1, CHARINDEX('-', @locale + '-') - 1) ELSE NULL END,
  'en'
 )
)


nl-nl -> 'nl-nl'
en -> 'en'
en-xxx -> 'en'
zz-gg -> 'en'
en-gb -> 'en-gb'
ff -> 'en'
0 голосов
/ 20 апреля 2010

Учитывая целевую культуру, верните либо полное совпадение, либо неудачное совпадение с родителем. (Предполагается, что осталось 2 символа из поля Культура)

(ОБНОВЛЕНО)

-- @TargetCulture represents the culture we are interested in
DECLARE @TargetCulture varchar(5)
SET @TargetCulture = 'nl-NL'

-- Parent represents the Result_Set (as in OP) plus column for the 'parent' culture
;WITH Parent AS
(
    SELECT 
        *, 
        LEFT(Culture, 2) AS parent
    FROM 
        Result_Set
)
SELECT 
    * 
FROM 
    Parent
WHERE
    -- Get either a full matching culture or just a match on the parent
    (@TargetCulture = Culture AND @TargetCulture <> parent)
    OR
    (@TargetCulture <> Culture AND @TargetCulture = parent)

Измените значение переменной @TargetCulture, чтобы получить культурные данные для nl, en-GB и en.

...