如何在CASE语句中分配多个值?

时间:2016-03-10 11:16:20

标签: sql sql-server case-statement

我需要根据CASE语句为select选择两个值。在伪:

snack

我正在为drink分配一个值。但是,我想我还想根据相同的条件为另一个变量select userid , case when name in ('A', 'B') then 'Apple' when name in ('C', 'D') then 'Pear' end as snack , case when name in ('A', 'B') then 'Milk' when name in ('C', 'D') then 'Cola' end as drink from table ; 分配一个值。一种方法是重复上述内容:

food

但是,如果我必须根据相同的条件分配更多值,请说drinkroomprint browser.find_element_by_xpath('/html/body/div/div/div[1]/div[2]/ul/li[2]/ul/li/span[3]/span[3]').text.encode("utf-8") 等。此代码很难维护。

有更好的方法吗?我可以把它放在SQL函数中,就像你通常用另一种(脚本)语言做的那样,如果有的话,你可以解释一下吗?

4 个答案:

答案 0 :(得分:3)

在做这样的事情时,我倾向于使用table valued constructor

的联接
SELECT  t.UserID,
        s.Snack,
        s.Drink
FROM    Table AS T
        LEFT JOIN
        (VALUES
            (1, 'Apple', 'Milk'),
            (2, 'Pear', 'Cola')
        ) AS s (Condition, Snack, Drink)
            ON s.Condition = CASE 
                                WHEN t.name IN ('A', 'B') THEN 1
                                WHEN t.name IN ('C', 'D') THEN 2
                            END;

如果我需要添加更多条件或列,我发现这是最灵活的。

或者更详细,但也更灵活:

SELECT  t.UserID,
        s.Snack,
        s.Drink
FROM    Table AS T
        LEFT JOIN
        (VALUES
            ('A', 'Apple', 'Milk'),
            ('B', 'Apple', 'Milk'),
            ('C', 'Pear', 'Cola'),
            ('D', 'Pear', 'Cola')
        ) AS s (Name, Snack, Drink)
            ON s.Name= t.name;

答案 1 :(得分:2)

功能会破坏性能。但是你可以使用common-table-expression(cte):

with cte as
(
    Select IsNameInList1 = case when name in ('A', 'B') 
                           then 1 else 0 end,
           IsNameInList2 = case when name in ('C', 'D') 
                           then 1 else 0 end,
           t.*
    from table
)
select
    userid
  , case when IsNameInList1=1 then 'Apple'
         when IsNameInList2=1 then 'Pear'
    end as snack
  , case when IsNameInList1=1 then 'Milk'
         when IsNameInList2=1 then 'Cola'
    end as drink
from
    cte
;

通过这种方式,你只有一个地方可以维持。

如果查询性能不重要,并且您想使用这样的标量值函数:

CREATE FUNCTION [dbo].[IsNameInList1] 
(
    @name varchar(100)
)
RETURNS bit
AS
BEGIN
DECLARE @isNameInList bit

BEGIN
    SET @isNameInList =  
    CASE WHEN @name in ('A', 'B')
    THEN 1
    ELSE 0 
    END
END

 RETURN @isNameInList 
END

然后您可以通过这种方式在查询中使用它:

select
    userid
  , case when dbo.IsNameInList1(name) = 1 then 'Apple'
         when dbo.IsNameInList2(name) = 1 then 'Pear'
    end as snack
from
    table
;

但更有效的方法是使用真实表来存储它们。

答案 2 :(得分:0)

希望这会对你有所帮助

SELECT userid
        ,(CASE flag WHEN 1 THEN 'Apple' WHEN 2 THEN 'Pear' WHEN 3 THEN '..etc' END ) as snack
        ,(CASE flag WHEN 1 THEN 'Milk'  WHEN 2 THEN 'Cola' WHEN 3 THEN '..etc' END ) as drink
FROM    (
    SELECT userid
            ,(  CASE    WHEN name IN ('A', 'B') THEN 1 
                    WHEN name IN ('C', 'D') THEN 2 
                    WHEN name IN ('X', 'Y') THEN 3
                ELSE 0 END )    AS flag
    FROM table ) t

答案 3 :(得分:0)

正如Ganesh在评论中建议的那样,我建议为此创建一个映射表并进行查找。插值,维护和扩展更加容易-所有这些都具有更好的性能。