Oracle SQL - подсчитать количество появлений текста в группе по выражению, если> = 1 текст, иначе else_text - PullRequest
0 голосов
/ 29 августа 2018

Я хочу сделать выборочное заявление, чтобы иметь обзор состояния каждого продукта. Статус продукта может быть либо 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

но это отклонено ошибкой

отсутствует правая скобка

Есть идеи?

Ответы [ 4 ]

0 голосов
/ 29 августа 2018

Поскольку у вас есть только два значения состояния ... это поможет!

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» в алфавитном порядке.

0 голосов
/ 29 августа 2018

В 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.

0 голосов
/ 29 августа 2018

Чтобы получить такой результат, вам, похоже, нужно на 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
0 голосов
/ 29 августа 2018

Вы должны использовать выборочную сумму, используя регистр для проверки правильных значений

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

и ваша группа должна включать все столбцы, не включенные в функцию агрегации

...