Как написать запрос, чтобы найти запись, которая не обрабатывается

Я пытаюсь написать запрос из таблицы A, которая имеет 2 столбца:

ID , STATUS

Статус может быть PROCESSING, NOTPROCESSED, FAILED, SUCCESS

Когда запись успешно обработана, в БД создается новая запись со СТАТУСОМ как PROCESSED, а идентификатор совпадает с предыдущей записью NOTPROCESSED.

Образцы записей в БД хотели бы:

1      NOTPROCESSED
2      PROCESSED
1      PROCESSED
3      NOTPROCESSED
4      NOTPROCESSED
2      PROCESSED
3      NOTPROCESSED
4      NOTPROCESSED

Записи могут отображаться как дубликаты для NOTPROCESSED.

Я должен запросить записи, которые NOTPROCESSED т.е.

3      NOTPROCESSED
4      NOTPROCESSED

Написание запроса становится довольно запутанным.

Может кто поможет с логикой.


person NIkhil Rohilla    schedule 28.12.2020    source источник


Ответы (4)


вы можете использовать не существует, чтобы получить этот вывод.

select distinct a.id,a.status
  from table a
 where a.status='NOTPROCESSED'
   and not exists (select null
                     from table b
                    where b.id=a.id
                      and b.status='PROCESSED')
person George Joseph    schedule 28.12.2020
comment
Это может работать, поскольку я создаю представление с выбранными столбцами из таблицы со всеми уникальными строками. Если в каком-то случае, если в таблице есть все уникальные строки, как изменится запрос? - person NIkhil Rohilla; 28.12.2020
comment
отдельная часть используется для подавления любых повторяющихся записей NONPROCESSED, принадлежащих этому идентификатору. Если комбинация (id,status) уникальна, то отдельное ключевое слово можно удалить. - person George Joseph; 28.12.2020
comment
Извините, не до конца написал. Я хотел сказать, что предположим, что в таблице есть больше столбцов, которые сделают идентификатор, СТАТУС, дублирующийся уникальным. Как в этом случае изменится запрос? - person NIkhil Rohilla; 28.12.2020

Сгруппируйте по id и возьмите только те группы, у которых нет записи о статусе PROCESSED

select id
from your_table
group by id
having sum(case when status = 'PROCESSED' then 1 else 0 end) = 0

или получить только те, у которых только один вид статуса

having count(distinct status) = 1

или используйте в алфавитном порядке самый высокий статус

having max(status) = 'NOTPROCESSED'
person juergen d    schedule 28.12.2020
comment
sum(status = 'PROCESSED') -- это не будет работать в Oracle... - person sticky bit; 28.12.2020
comment
Забыл это. Спасибо. - person juergen d; 28.12.2020

Вот несколько вариантов:

select distinct id from A where id not in (
  select id from A where status = 'PROCESSED'
);

select distinct id from A natural left join (
  select id from A where status = 'PROCESSED'
) as B where B.id is null;
person Allan Wind    schedule 28.12.2020
comment
Кажется, это работает, когда я выполняю запрос в SQLDeveloper, но когда я выполняю его в своем java-коде с помощью jdbcTemplate.query, он все равно извлекает дублирующуюся запись, которая обрабатывается в следующей строке. - person NIkhil Rohilla; 28.12.2020

Вы можете использовать аналитическую функцию следующим образом:

select * from
(select t.*, count(case when status = 'PROCESSED' then 1 end)
                   over (partition by ID) as cnt
from your_table t) t
where status = 'NOTPROCESSED' and cnt = 0
person Popeye    schedule 28.12.2020