相同列的多个案例语句的替代方法

时间:2013-09-16 21:30:50

标签: sql-server-2008 tsql

为了将一些新模式与旧模式相匹配,我不得不做一些丑陋的扭曲,我认为可以以更好的方式完成。作为参考,我在这里提出了有关此匹配过程的另一个问题:Creating View from Related Child Tables

我在SQLFiddle中放置了一个简化的例子,但它的要点是,我能看到调和这两个不同模式的唯一方法是对相同的值做两个case语句,如下所示:

SELECT 
    CASE 
        WHEN n.FooBarStatusId = 1 OR n.FooBarStatusId = 2 
            THEN 1 
        ELSE 0 
    END as [IsFoo],
    CASE
        WHEN n.FooBarStatusId = 2
            THEN 1
        ELSE 0
    END as [IsBar]
from Parent p
left join OldStuff o on p.ParentId = o.ParentId
left join NewStuff n on p.ParentId = n.ParentId

是否有更好和/或更有效的方法来完成同样的事情?在给定的查询中,这些case语句可能会被击中数百次,我担心这个特定的逻辑。

我已经考虑过将这个特定逻辑(它是构建视图的更大查询的一部分)提取到临时表或者甚至是表值函数中,但即便如此,我仍然无法想出使用多个案例陈述的方法。

2 个答案:

答案 0 :(得分:1)

由于您有两列,需要两个表达式......但它们可能不一定是CASE个表达式。阅读你的问题,我得到的印象是,列中唯一可能的值是0,1,2,这是int类型?如果这是正确的,你可以使用算术而不是布尔逻辑来获得你需要的东西。试试这个:

CAST( (n.FooBarStatusId % .35) * 4 AS int) AS [IsFoo],
n.FooBarStatusId/2 [IsBar]

答案 1 :(得分:1)

刚刚纠正的语法......

我找到了另一个解决方案:

select 
 p.Name,
 ISNULL(o.IsFoo, CONVERT(BIT, n.FooBarStatusId)) as [IsFoo],
 ISNULL(o.IsBar, CONVERT(BIT, n.FooBarStatusId * (n.FooBarStatusId - 1))) as [IsBar],
from Parent p
left join OldStuff o on p.ParentId = o.ParentId
left join NewStuff n on p.ParentId = n.ParentId

唯一一个算术解决方案可能很慢:

select 
 p.Name,
 ISNULL(o.IsFoo, CAST( (n.FooBarStatusId % 0.35) * 4 AS int)) AS [IsFoo],
 ISNULL(o.IsBar, n.FooBarStatusId/2) [IsBar]
from Parent p
left join OldStuff o on p.ParentId = o.ParentId
left join NewStuff n on p.ParentId = n.ParentId

就个人而言,我不喜欢使用除法,因为可能涉及浮点运算,这样,它会很慢。