【问题标题】:Oracle - counting the result of a CASE statementOracle - 计算 CASE 语句的结果
【发布时间】:2012-12-22 09:16:38
【问题描述】:

目标/背景

  • 我正在梳理工单系统以查看工单是否符合特定标准
    • (例如,如果它们不是第 3 阶段、第 2 阶段甚至第 1 阶段)。
  • 这些“阶段”已由管理层定义。
  • 我想按报告的年份分组,然后按工艺分组,然后查看该分组的工作订单在这 3 个“非阶段”的每一个中都有多少。

查询

select yearreported
, theleadcraft
, count(NotStage3)
, count(NotStage2)
, count(NotStage1)

from
(
    select extract(year from reportdate) as YearReported
    , Nvl(leadcraft, 'NONE') as TheLeadCraft
    , CASE when status not in ('CAN', 'CLOSE') then 1 else 0 END as NotStage3
    , CASE when status not in ('CAN', 'CLOSE', 'COMP') then 1 else 0 END as NotStage2
    , CASE when status not in ('CAN', 'CLOSE', 'COMP', 'WORKDONE') then 1 else 0  END as NotStage1
    from workorder
) query 

group by yearreported, theleadcraft;
;

问题/问题

  • 这似乎有效,但 notstage1、notstage2 和 notstage1 的所有计数都相同,尽管查询了某些情况并发现了一些我知道不同的情况。
  • 这是实现我要计算的 case 语句的正确方法吗?
  • 我应该改用 DECODE() 吗?

提前感谢您的帮助!

【问题讨论】:

标签: sql oracle plsql count case


【解决方案1】:

是的,您可以通过对上面的语句进行简单修改来做到这一点

试试这个:

select yearreported
, theleadcraft
, count(decode (NotStage3, 1,1) )
, count(decode (NotStage2, 1,1) )
, count(decode (NotStage1, 1,1) )

from
(
    select extract(year from reportdate) as YearReported
    , Nvl(leadcraft, 'NONE') as TheLeadCraft
    , CASE when status not in ('CAN', 'CLOSE') then 1 else 0 END as NotStage3
    , CASE when status not in ('CAN', 'CLOSE', 'COMP') then 1 else 0 END as NotStage2
    , CASE when status not in ('CAN', 'CLOSE', 'COMP', 'WORKDONE') then 1 else 0  END as NotStage1
    from workorder
) query 

group by yearreported, theleadcraft;

问候,

【讨论】:

  • 这个技巧使用decode函数,1s的值返回1,所有其他的值都不会解码,然后decode函数会返回null,所以不计入。
【解决方案2】:

你不应该使用decode

按照您编写查询的方式,您真正想要的是sum(),而不是count()

select yearreported, theleadcraft, sum(NotStage3), sum(NotStage2), sum(NotStage1)

函数count() 在应用于列时具有误导性名称(在我看来)。它正在计算非 NULL 值的数量。由于 "1" 和 "0" 都不是 NULL,所以它们都被计算在内。

【讨论】:

    【解决方案3】:

    1 和 0 的 COUNT() 相同 -- 可能您想要 SUM() 或 COUNT() 1 或 null。

    【讨论】:

    • 谢谢!这确实是一个脑放屁——我之前在以不同的方式看待问题时一直在使用 count 并且没有调整我的聚合函数。 :) 谢谢!
    • 零算作 1。多么令人困惑 :) Null 是关键。谢谢。
    【解决方案4】:

    Count 不计算 NULL -s。试试这个:

    , CASE when status not in ('CAN', 'CLOSE') then 1 END as NotStage3
    , CASE when status not in ('CAN', 'CLOSE', 'COMP') then 1 END as NotStage2
    , CASE when status not in ('CAN', 'CLOSE', 'COMP', 'WORKDONE') then 1 END as NotStage1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-22
      • 1970-01-01
      • 2011-09-15
      • 2021-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多