问题描述
我有带有以下各列的表。
对于上表,我需要获取每个cd的按日期计数,具体取决于ind值组合,并期望下面的输出表。
对于输出表中的row2,id为45的一个OK和一个NO不存在,因此对于2020-02-24日期,由于1正常,因此需要算为1。
类似地,对于第4行,它具有nook和no,因此对于此组合,我们需要为id为30的最大日期采用notok
我需要在配置单元中进行开发,有人可以建议我们如何实现此目标。我尝试编写单独的子查询,但是由于连接很多而导致性能下降(我正在编写单独的查询以分别计算每个组合并连接结果)
已针对其他情况进行了更新:
我在表中有以下数据。
当我们称重时,它看起来如下
第一种情况:当我们按日期分组时,对于2020年1月1日,我得到了正确的计数1
第二种情况:对于日期1/2/2020,我们假设对notOk仅获得计数1,但它给出2(因为它正在为CD 1寻找1/2/2020的第一种情况行。
还有另一个场景:
当我在不同日期有同一张CD的多个记录时,没有给出正确的结果。
在不同的日期,我对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