我想制作一个select语句,以概述每个产品的状态。产品的状态可以是OK
或NOT_OK
,产品可以多次测试。我希望每个产品都具有“最差”状态:如果产品已经至少测试过一次NOT_OK
和NOT_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
但这被错误拒绝了
缺少右括号
你有什么主意吗?
为了得到这个结果,你似乎需要一个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
在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
中。
您应该使用案例的选择性总和来检查正确的值
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必须包含所有未参与聚合函数的列
因为你只有两个状态值......这样就可以了!
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”。