【问题标题】:Conditional count when case = 1, DB2case = 1 时的条件计数,DB2
【发布时间】:2019-10-07 10:56:03
【问题描述】:

我目前正在尝试找出在 DB2 for Iseries 中将条件计数作为别名的最佳方法。以下值表示可以创建、完成和取消作业的作业状态,因此任何一项作业都可能附加多个状态代码。

但是,对于我的最终价值,我正在尝试计算仅具有已创建状态的工作,以便我可以显示仍有多少工作处于开放状态。基本上寻找创建案例的计数= 1的案例,但以下在'='处失败

SELECT
  COUNT(CASE A1.JOB WHEN = 'CREATED' THEN 1 END) AS CREATED,
  COUNT(CASE A1.JOB WHEN = 'CANCELLED' THEN 1 END) AS CANCELLED,
  COUNT(CASE WHEN A1.JOB 'CREATED' = 1 then 1  END)  AS OPEN
FROM SCHEMA.TABLE A1;

样本数据和结果:

    Job ID   |   Status_code
-------------------------
123         'CREATED'
123         'COMPLETED'
521         'CREATED'
521         'CANCELLED'
645         'CREATED'

结果:

JOB  |  CREATED  |   CANCELLED   |   OPEN
-------------------------------------------
123     1               0               0
521     1               1               0
645     1               0               1

【问题讨论】:

  • 样本数据和期望的结果会有所帮助。
  • @GordonLinoff 抱歉,现在才添加

标签: sql db2 db2-400


【解决方案1】:

假设唯一的“关闭”状态是'CANCELLED',您可以像这样使用not exists

select count(*)
from schema.table t
where t.status_code = 'CREATED' and
      not exists (select 1
                  from schema.table t2
                  where t2.job = t.job and
                        t2.status_code in ('CANCELLED', 'COMPLETED', 'DELETED')
                 );

如果您想要多个计数,则这样的过滤不起作用。所以先按作业汇总:

select sum(is_created) as num_created,
       sum(is_cancelled) as num_cancelled,
       sum(is_created * (1 - is_cancelled) * (1 - is_completed) * (1 - is_deleted)) as open
from (select job,
             max(case when status_code = 'CREATED' then 1 else 0 end) as is_created,
             max(case when status_code = 'CANCELLED' then 1 else 0 end) as is_cancelled,
             max(case when status_code = 'COMPLETED' then 1 else 0 end) as is_completed,
             max(case when status_code = 'DELETED' then 1 else 0 end) as is_deleted
      from t
      group by job
     ) j

【讨论】:

  • 抱歉,我试图更好地澄清我的问题,但从技术上讲,它们可以作为结束状态完成、取消或删除
  • 但是对于这个特定的查询,我只是想显示创建、取消和打开
【解决方案2】:

以下返回你需要的结果:

WITH TAB (Job_ID, JOB) AS 
(
VALUES
  (123, 'CREATED')
, (123, 'COMPLETED')
, (521, 'CREATED')
, (521, 'CANCELLED')
, (645, 'CREATED')
)
SELECT
  Job_ID
, COUNT(CASE A1.JOB WHEN 'CREATED'   THEN 1 END) AS CREATED
, COUNT(CASE A1.JOB WHEN 'CANCELLED' THEN 1 END) AS CANCELLED
, CASE 
    WHEN NULLIF(COUNT(1), 0) = COUNT(CASE A1.JOB WHEN 'CREATED' then 1 END) 
    THEN 1 
    ELSE 0 
  END AS OPEN
FROM TAB A1
GROUP BY JOB_ID;

【讨论】:

    【解决方案3】:

    使用条件聚合:

    SELECT
      JobID,
      MAX(CASE Status_code WHEN 'CREATED' THEN 1 ELSE 0 END) AS CREATED,
      MAX(CASE Status_code WHEN 'CANCELLED' THEN 1 ELSE 0 END) AS CANCELLED,
      MIN(CASE WHEN Status_code <> 'CREATED' THEN 0 ELSE 1 END) AS OPEN
    FROM tablename 
    GROUP BY JobID 
    

    请参阅demo
    结果:

    > JobID | CREATED | CANCELLED | OPEN
    > ----: | ------: | --------: | ---:
    >   123 |       1 |         0 |    0
    >   521 |       1 |         1 |    0
    >   645 |       1 |         0 |    1
    

    【讨论】:

      【解决方案4】:

      假设有效的关闭状态是“COMPLETED”或“CANCELLED”,您可以尝试以下 SQL。

      SELECT
        A1.JobID,
        sum(CASE  WHEN A1.Status_code = 'CREATED' THEN 1 ELSE 0 END) AS CREATED,
        sum(CASE  WHEN  A1.Status_code = 'CANCELLED' THEN 1 ELSE 0 END) AS CANCELLED,
        (
           SUM(CASE WHEN A1.Status_code = 'CREATED' THEN 1 ELSE 0 END)
         - sum(CASE WHEN A1.Status_code = 'CANCELLED' THEN 1 ELSE 0 END)
         - sum(CASE WHEN A1.Status_code = 'COMPLETED' THEN 1 ELSE 0 END)
       ) AS OPEN
      FROM SCHEMA.TABLE A1
      GROUP BY A1.JobID 
      

      【讨论】:

      • 谢谢!这是给我正确数据的唯一选项,所以我接受了它
      • @TomN。 唯一选项是什么意思?
      • @TomN。您接受了一个错误的答案,因为它会在为相同的jobid竞争、取消和创建时返回-1dbfiddle.uk/…
      • @forpas 好点,但它是给我适当数据的唯一解决方案,但不应该有这些情况。是否有解决 -1 问题的好方法?
      • 这是给我适当数据的唯一解决方案你在说什么?我在答案中发布了一个小提琴演示,您可以在其中看到它返回正确的结果。
      猜你喜欢
      • 2016-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多