根据蜂巢中的列值获取每种可能性的总和-汇总表

问题描述

我有带有以下各列的表。

enter image description here

对于上表,我需要获取每个cd的按日期计数,具体取决于ind值组合,并期望下面的输出表。

enter image description here

对于输出表中的row2,id为45的一个OK和一个NO不存在,因此对于2020-02-24日期,由于1正常,因此需要算为1。

类似地,对于第4行,它具有nook和no,因此对于此组合,我们需要为id为30的最大日期采用notok

我需要在配置单元中进行开发,有人可以建议我们如何实现此目标。我尝试编写单独的子查询,但是由于连接很多而导致性能下降(我正在编写单独的查询以分别计算每个组合并连接结果)

已针对其他情况进行了更新:

我在表中有以下数据。

enter image description here

当我们称重时,它看起来如下

enter image description here

第一种情况:当我们按日期分组时,对于2020年1月1日,我得到了正确的计数1

第二种情况:对于日期1/2/2020,我们假设对notOk仅获得计数1,但它给出2(因为它正在为CD 1寻找1/2/2020的第一种情况行。

还有另一个场景:

当我在不同日期有同一张CD的多个记录时,没有给出正确的结果。

enter image description here

在不同的日期,我对CD 1有2个“ ok”。因此,我们只考虑计数1,就需要丢弃其他ok,因为对于同一张cd,它是1/1/2020或1/2/2020。

非常感谢您的帮助。

谢谢, 巴布

解决方法

如果您需要对给定ID的最新日期进行ind计数,则查询将如下所示

select dt,count(case when ind='ok' then 1 end) as ok_count,count(case when ind='No' then 1 end) as No_count,count(case when ind='not ok' then 1 end) as not_ok_count 
from mytable_test where dt in (select max(dt) from mytable_test group by cd) group by dt;

但是,如果存在某些真值表条件,例如:对于给定的ID,
-如果同时具有“确定”和“否”,则选择“确定”。 -如果同时显示“否”和“不正常”,请选择“不正常”。

然后它可能不是一个非常有效的方法,但是会很好用。

select dt,count(case when ind='not ok' then 1 end) as not_ok_count 
from mytable_test where dt in (
select max(a.dt) from mytable_test a,(select cd,(case when ind_to_consider=0 then 'No' when ind_to_consider=1 then 'ok' when ind_to_consider=2 then 'not ok' end ) as decoeded_ind from  (select cd,max(ind_wt) as ind_to_consider from (select dt,cd,ind,(case when ind='ok' then 1 when ind='No' then 0 when ind='not ok' then 2 end ) as ind_wt from  mytable_test) wt group by cd) decoder) k where a.cd=k.cd and a.ind=k.decoeded_ind group by a.cd,a.ind)  group by dt;

解释

首先提供您提供的ind条件的权重。 在这种情况下,根据您的示例,我假设NOK的权重最低,中等程度可以,而不是最高。

select dt,(case when ind='ok' then 1 when ind='No' then 0 when ind='not ok' then 2 end ) as ind_wt from  mytable_test

    +-------------+-----+---------+---------+--+
    |     dt      | cd  |   ind   | ind_wt  |
    +-------------+-----+---------+---------+--+
    | 2020-08-24  | 10  | ok      | 1       |
    | 2020-02-21  | 45  | No      | 0       |
    | 2020-02-24  | 45  | ok      | 1       |
    | 2020-08-25  | 20  | No      | 0       |
    | 2020-10-09  | 30  | not ok  | 2       |
    | 2020-10-13  | 30  | not ok  | 2       |
    | 2020-10-21  | 30  | No      | 0       |
    | 2020-10-23  | 30  | No      | 0       |
    | 2020-09-14  | 12  | No      | 0       |
    +-------------+-----+---------+---------+--+

下一步获取每个CD的最大重量(在wt块中)

select cd,(case when ind='ok' then 1 when ind='No' then 0 when ind='not ok' then 2 end ) as ind_wt from  mytable_test) wt group by cd

+-----+------------------+--+
| cd  | ind_to_consider  |
+-----+------------------+--+
| 10  | 1                |
| 12  | 0                |
| 20  | 0                |
| 30  | 2                |
| 45  | 1                |
+-----+------------------+--+

现在,您必须将权重解码回指标,以便获取每个cd和max指标的最新日期。

select max(a.dt) from mytable_test a,a.ind

+-------------+--+
|     _c0     |
+-------------+--+
| 2020-08-24  |
| 2020-09-14  |
| 2020-08-25  |
| 2020-10-13  |
| 2020-02-24  |
+-------------+--+

然后使用这些日期获取海盗

select dt,a.ind)  group by dt;



+-------------+-----------+-----------+---------------+--+
|     dt      | ok_count  | no_count  | not_ok_count  |
+-------------+-----------+-----------+---------------+--+
| 2020-02-24  | 1         | 0         | 0             |
| 2020-08-24  | 1         | 0         | 0             |
| 2020-08-25  | 0         | 1         | 0             |
| 2020-09-14  | 0         | 1         | 0             |
| 2020-10-13  | 0         | 0         | 1             |
+-------------+-----------+-----------+---------------+--+
,

使用条件聚合:

select date,sum(case when ind = 'ok'     then 1 else 0 end) ok_count,sum(case when ind = 'No'     then 1 else 0 end) no_count,sum(case when ind = 'not ok' then 1 else 0 end) not_ok_count
from mytable
group by date

或者,如果您只考虑每个id的最新行,我们可以先使用row_number()进行预过滤:

select date,sum(case when ind = 'not ok' then 1 else 0 end) not_ok_count
from (
    select t.*,row_number() over(partition by id order by date desc) rn
    from mytable t
) t
where rn = 1
group by date