选择查询中的SQL案例

时间:2010-10-20 23:08:07

标签: sql-server case

我有以下查询

Select
        a,b,c,
        case totalcount
            when 0 then 0
            else abcd/totalcount
        end AS 'd',
        case totalcount
            when 0 then 0
            else defg/totalcount
        end AS 'e'
    From 
        Table1

在这个查询中,我在select查询中有相同的case语句...我可以把它变成单个select语句。

“totalcount”是一些值... abcd和defg是table1中的两个列值。如果totalcount为零,我不想分割,否则我希望除以得到abcd和defg的平均值。

5 个答案:

答案 0 :(得分:1)

不,因为您似乎需要在所需结果集中使用两个输出列...每个Case语句最多只能生成一个输出值。

case语句需要访问多少列才能完成它的工作,或者它必须选择多少个不同的值(多少When... Then...个表达式),这与你有多少列无关紧要正在尝试在最终结果集中生成。

答案 1 :(得分:0)

在第一个视图中,我会说不,因为您似乎使用完全相同的条件导致不同的结果。

此外,这对我来说很奇怪,为什么你只需要两个SELECT CASE只有一个条件?这毫无意义。

您是否可以通过“真实”数据更具体或提供您尝试提出的实际示例,以便我们更好地回答您的问题?

编辑#1

鉴于:

  

是的......这是两个不同的领域....我需要的价值计算一个......这是值= a / b。但我需要检查b是否为零

我仍然会回答不,好像它们是两个不同的字段,并且您希望结果集中都有结果,那么您需要编写两个CASE语句,每个字段对应您需要的每个字段验证它是否为零值。请记住,一个CASE语句仅相当于一个列。因此,如果您需要检查零值,则需要单独检查两者。

顺便说一句,对不起我的误解,不幸的是,这一定是语言障碍。 =)但我对“真实”数据示例的要求仍然存在,因为这可能会使我们所有人都了解其他相关解决方案,我们永远不会知道! =)

编辑#2

考虑到您必须检查0的值,为了便于阅读,我可能会按如下方式重写我的代码:

select a, b, c
        , case when condition1 <> 0 then abcd / condition1 else 0 end as Result1
        , case when condition2 <> 0 then defg / condition2 else 0 end as Result2
    from Table1

在我看来,它在代码中更精简,更容易理解意图是什么。但毕竟,结果会是一样的!这里没有冒犯! =)

编辑#3

阅读完问题编辑后:

  

“totalcount”是一些值... abcd和defg是table1中的两个列值。如果totalcount为零,我不想分开,否则我希望除以得到abcd和defg的平均值值。

我说,如果是你所追求的平均值,为什么不使用AVG函数来处理它,而不必关心零值?

select a, b, c
        , AVG(abcd) as Result1
        , AVG(defg) as Result2
    from Table1

另外,考虑到没有记录,平均值只能是0!

我不知道您的数据库引擎,但如果它是Oracle或SQL Server,我认为DB2也支持这个功能。

答案 2 :(得分:0)

你需要详细说明 - 条件是什么?根据您到目前为止输入的内容,看起来您只是使用表达式的结果,使CASE语句变得多余。

例如,请参阅我的内联评论:

SELECT a,b,c,
    case condition
        when 0 then 0        --this is unnecessary
        else abcd/condition, --this is just using the result of the condition?
    case condition
        when 0 then 0        --this is unnecessary
        else defg/condition  --this is just using the result of the condition?
from Table1

所以你可以将它重构为:

SELECT  a
       ,b
       ,c
       ,expression
       ,expression 
from Table1

如果您实际上意味着else abcd/condition 评估另一个条件或使用默认值,那么您需要对其进行扩展,以便我们能够准确回答。

编辑:如果您希望避免除以零而您只想评估条件一次,那么您需要在SELECT之外进行并使用SELECT中的变量。我不会担心多次评估它的性能影响,如果condition没有改变,那么它的值应该被查询执行引擎缓存。虽然它可能看起来很丑陋且不可维护,但在这种情况下,您可能会将condition分解为函数。

答案 3 :(得分:0)

如果您要做的就是避免除以零,如果除以零的尝试实际上产生零并不重要,那么您可以执行以下操作:

Select
    a,b,c,
    abcd / NULLIF(totalcount,0) AS 'd',
    defg / NULLIF(totalcount,0) AS 'e'
From 
    Table1

这会将尝试除以零转换为尝试除以NULL,这总是产生NULL。

如果你需要零并且你知道abcddefg永远不会是NULL,那么你可以将整个事物包装在ISNULL(...,0)中以强制它为零。如果abcddefg可能合法地为空并且如果totalcount为零则您需要零输出,那么我不知道除了使用CASE语句之外的任何其他选项,抱歉。

此外,由于totalcount似乎是一个表达式,为了可维护性,您可以在子查询中计算它,例如:

Select
    a,b,c,
    abcd / NULLIF(totalcount,0) AS 'd',
    defg / NULLIF(totalcount,0) AS 'e'
From 
(
    Select
        a,b,c,
        abcd,
        defg,
        (... expression goes here ...) AS totalcount
    From 
        Table1
) Data

但如果这是一个简单的表达,这可能有点过分。

答案 4 :(得分:0)

从技术上讲,这是可能的。我不是在暗示这是一个好主意!

;with Table1 as
(
select 1 as a, 2 as b, 3 as c, 0 as condition, 1234 as abcd, 4567 AS defg UNION ALL
select 1 as a, 2 as b, 3 as c, 1 as condition, 1234.0 as abcd, 4567 AS defg 
)
,
cte AS
(
Select
a,b,c,
case condition
    when 0 then CAST(CAST(0 as decimal(18, 6)) as binary(9)) + CAST(CAST(0 as decimal(18, 6)) as binary(9))
    else CAST(CAST(abcd/condition as decimal(18, 6)) as binary(9)) + CAST(CAST(defg/condition as decimal(18, 6)) as binary(9))
end AS d
From 
Table1
)
Select
     a,
     b,
     c, 
     cast(substring(d,1,9) as decimal(18, 6)) as d, 
     cast(substring(d,10,9) as decimal(18, 6)) as e
From cte