【问题标题】:Conditional grouping based on 2 values in same field基于同一字段中的 2 个值的条件分组
【发布时间】:2020-12-29 08:46:37
【问题描述】:

我有如下数据

Number      ActivityID   UnitID          Description                     Date
1231          3456        334      Issue                     2020-12-01 23:02:44
1231          3457        334      Restarted                 2020-12-01 23:45:44
1231          3458        334      closed till 31-12-9999    2020-12-01 23:46:32
1232          4532        445      Issue                     2020-12-01 23:45:44
1232          4533        445      closed till 31-12-9999    2020-12-01 23:67:44

Number 是票号,Activity 是票号中所有活动的唯一 ID,UnitId 是产品的编号,action 是对解决问题的描述和日期。

当一个工单活动被重新启动然后关闭到 31-12-9999 时,这意味着它在 App-A 中被重新启动。

如果工单仅“关闭至 31-12-9999”且之前没有重新启动活动,则表示它已在 app-B 中重新启动。

我的预期结果:

month        AppA       AppB
Dec 2020      1          1

我试图用下面的查询来计算它们的数量,

select Format(Date, 'MMMM-yyyy') as Month, sum(AppA) as AppA, sum(AppB) as AppB
from (
    select Date, Description,
        case when lower(Description) like '%31-12-9999%' then 1 else 0 end as AppB, 
        case when lower(Description) like '%Restarted%' then 1 else 0 end as AppA
    from  fct.SurveillanceAction
) a
group by Format(Date, 'MMMM-yyyy')

我不知道如何在逻辑上编写 AppA 计数(当工单活动重新启动然后关闭到 31-12-9999 然后 1)

条件是:

  1. App A 之前只有 31-12-9999 并且没有“重新启动”消息。它应该只计算那些没有重新启动但有 31-12-9999 的人。
  2. AppB 具有“31-12-9999”和重新启动消息,只有在两者连续时才应考虑。

谁能帮帮我?

【问题讨论】:

  • “月”基于什么日期?
  • @GordonLinoff,日期字段。即活动发生的时间。

标签: sql sql-server ssms


【解决方案1】:

你需要解析函数,然后条件group by如下:

select Format(Date, 'MMMM-yyyy') as Month, 
       count(case when AppA> 0 and AppB> 0 then 1 end) as AppA, 
       count(case when AppA> 0 and AppB = 0 then 1 end) as AppB
from (select  Date, Description,
              count(case when lower(Description) like '%31-12-9999%' then 1 end) 
                    over (partition by number) as AppB, 
              count(case when lower(Description) like '%Restarted%' then 1 end) 
                    over (partition by number) as AppA
        from  fct.SurveillanceAction)a
group by Format(Date, 'MMMM-yyyy')

如果Restartedclosed till 31-12-9999 的顺序很重要,那么您可以使用以下查询:

select Format(Date, 'MMMM-yyyy') as Month, 
       count(case when AppA > AppB then 1 end) as AppA, 
       count(case when AppB is null or AppA < AppB then 1 end) as AppB
from (select  Date, Action,
              max(case when lower(Description) like '%31-12-9999%' then Date end) 
                    over (partition by number) as AppB, 
              max(case when lower(Description) like '%Restarted%' then Date end) 
                    over (partition by number) as AppA
        from  fct.SurveillanceAction)a
group by Format(Date, 'MMMM-yyyy')

-- 更新

如果您只需要在 Restartedclosed till 31-12-9999 连续时进行计数,请使用以下查询:

select Format(Date, 'MMMM-yyyy') as Month, 
       count(case when lower(Description) like '%31-12-9999%' 
             and cnt = 0 then 1 end) as AppA, 
       count(case when lower(Description) like '%31-12-9999%' 
             and lower(lg_Description) like '%Restarted%' then 1 end) as AppB
from (select  Date, Action,
              lag(Description)  
                over (partition by number order by date) as lg_description,
              count(case when lower(Description) like '%Restarted%' then 1 end)
                over (partition by number order by date) as cnt_restarted
        from  fct.SurveillanceAction)a
group by Format(Date, 'MMMM-yyyy')

【讨论】:

  • 这很好,但我认为它也会考虑 Restarted 和 31-12-9999 ,即使它们不相邻,对吗?有办法避免吗?
  • 条件是: 1. App A只有31-12-9999,之前没有“restarted”消息。它应该只计算那些没有重新启动但有 31-12-9999 的消息...... 2. AppB 有“31-12-9999”和重新启动的消息,只有在两者都是连续的情况下才应该考虑。
  • 好的,请参阅我添加了重新启动计数的更新答案。
  • 更新的答案效果最好!再次感谢:)
【解决方案2】:

假设工单仅关闭并重新启动一次(如您的示例数据中所示),那么您可以使用两个级别的聚合:

select year(max_date), month(max_date),
       sum(is_restart) as A,
       sum(1 - is_restart) as B
from (select number,
             max(case when lg_description = 'Restarted' then 1 else 0 end) as is_restart,
             max(case when lg_description = 'closed till 31-12-9999' then 1 else 0 end) as is_close,
             max(date) as max_date
      from fct.SurveillanceAction sa
      group by number
     ) n
where is_close = 1
group by year(max_date), month(max_date)
order by year(max_date), month(max_date);

月份与number 的最大日期相关联,这似乎总是示例数据的“关闭”。

(这将年份和月份放在不同的列中;这似乎不是问题的重要部分。)

【讨论】:

    猜你喜欢
    • 2018-09-20
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 2017-10-21
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多