Oracle SQL - 按表达式计算组中文本的出现次数,如果> = 1 text,则为another_text

问题描述 投票:2回答:4

我想制作一个select语句,以概述每个产品的状态。产品的状态可以是OKNOT_OK,产品可以多次测试。我希望每个产品都具有“最差”状态:如果产品已经至少测试过一次NOT_OKNOT_OK,我希望有OK


这是一个小数据样本:

PRODUCT | STATUS    | DATA_PRODUCT_SPECIFIC_TO_KEEP
--------+-----------+--------------------------------
A       | NOT_OK    | AAA
A       | OK        | AAA
B       | OK        | BBB
B       | OK        | BBB
B       | OK        | BBB
C       | NOT_OK    | CCC

这是我期望得到的结果:

PRODUCT | STATUS    | DATA_PRODUCT_SPECIFIC_TO_KEEP
--------+-----------+--------------------------------
A       | NOT_OK    | AAA
B       | OK        | BBB
C       | NOT_OK    | CCC

我试着使用下面的查询:

SELECT PRODUCT, count(STATUS="NOT_OK"), DATA_PRODUCT_SPECIFIC_TO_KEEP
FROM TABLE 
GROUP BY PRODUCT

但这被错误拒绝了

缺少右括号

你有什么主意吗?

sql oracle group-by aggregate
4个回答
2
投票

为了得到这个结果,你似乎需要一个MIN而不是COUNT;有你的数据,这个

select product, min(status), data_product_specific_to_keep
from yourtable
group by product, data_product_specific_to_keep

得到:

A       NOT_OK      AAA                          
B       OK          BBB                          
C       NOT_OK      CCC 

如果需要处理两个以上的值,则必须定义优先级逻辑;您可以使用以下内容实现它:

select PRODUCT,
       case (status)
           when 2 then 'NOT_OK'
           when 1 then 'AWAIT'
           else 'OK'
       end,
       DATA_PRODUCT_SPECIFIC_TO_KEEP
from (
        select min(
                   case (status)
                     when 'NOT_OK' then 2
                     when 'AWAIT' then 1
                     else 0
                   end
                  ) as status,
               PRODUCT, DATA_PRODUCT_SPECIFIC_TO_KEEP
        from yourTable
        group by PRODUCT, DATA_PRODUCT_SPECIFIC_TO_KEEP
)
order by 1

有这样的表

create table yourTable (PRODUCT, STATUS, DATA_PRODUCT_SPECIFIC_TO_KEEP) as (
    select 'A', 'NOT_OK', 'AAA' from dual union all
    select 'A', 'OK', 'AAA' from dual union all
    select 'B', 'OK', 'BBB' from dual union all
    select 'B', 'AWAIT', 'BBB' from dual union all
    select 'B', 'OK', 'BBB' from dual union all
    select 'C', 'NOT_OK', 'CCC' from dual union all
    select 'C', 'AWAIT', 'CCC' from dual union all
    select 'D', 'NOT_OK', 'DDD' from dual union all
    select 'D', 'NOT_OK', 'DDD' from dual
)

结果将是

P CASE(S DAT
- ------ ---
A OK     AAA
B OK     BBB
C AWAIT  CCC
D NOT_OK DDD

2
投票

在Oracle中,你需要一个case表达式。但你还需要修复GROUP BY

SELECT PRODUCT, SUM(CASE WHEN STATUS = 'NOT_OK' THEN 1 ELSE 0 END) as not_ok_cnt, 
       DATA_PRODUCT_SPECIFIC_TO_KEEP
FROM TABLE 
GROUP BY PRODUCT, DATA_PRODUCT_SPECIFIC_TO_KEEP;

所有非聚合列都需要在GROUP BY中。


2
投票

您应该使用案例的选择性总和来检查正确的值

SELECT PRODUCT, 
       sum(case  STATUS="NOT_OK" then 1 else  0 END), 
       DATA_PRODUCT_SPECIFIC_TO_KEEP
FROM TABLE 
GROUP BY PRODUCT, DATA_PRODUCT_SPECIFIC_TO_KEEP

并且您的group by必须包含所有未参与聚合函数的列


1
投票

因为你只有两个状态值......这样就可以了!

SELECT t.PRODUCT, MIN(t.STATUS), t.DATA_PRODUCT_SPECIFIC_TO_KEEP
  FROM yourTable t
 GROUP BY t.PRODUCT, t.DATA_PRODUCT_SPECIFIC_TO_KEEP

这将提取每个产品的最小字符串值,并且“N”按字母顺序恰好小于“O”。

© www.soinside.com 2019 - 2024. All rights reserved.