T-SQL Where语句 - 或者

时间:2010-04-20 11:43:30

标签: sql-server tsql linq-to-entities where

对于模糊的标题感到抱歉,但我真的不知道给这个问题的标题:

我有以下结果集:

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'

或者当父文化没有结果时,请尝试默认的Culture(en)

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

如何在一个T-SQL语句中组合这些SELECT语句?
我正在使用LINQ,因此LINQ表达式会更大。

OR声明不起作用,因为我不想混合各种文化 ORDER BY语句无济于事,因为它会为每种文化返回多个记录。

输出可能看起来像(nl-NL):

Color   Groen
Taste   Kip

或(en-GB / en):

Color   Green
Taste   Chicken

5 个答案:

答案 0 :(得分:4)

因此,这里的代码完全按照您的示例编写。 您可以在客户端代码中确定特定的文化(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
)

您确定需要针对特定​​文化的整个翻译表,而不是每个字符串的翻译吗?如果在en中有字符串A和B,但在nl-NL中只有字符串A

,该怎么办?

答案 1 :(得分:2)

试试这个:

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
        );

答案 2 :(得分:1)

假设@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 =完整文化。

答案 3 :(得分:0)

给定目标文化返回完全匹配,或者失败匹配父项。 (假设是文化领域的左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变量的值,以检索nlen-GBen的文化数据。

答案 4 :(得分:0)

另一种方法;

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'