Условно выберите данные, которые обновляются после ошибки в новой строке - PullRequest
1 голос
/ 08 мая 2019

У меня есть приложение, которое записывает данные в базу данных. Если какая-то запись содержит ошибку, а затем пользователь добавляет новые данные, он добавляет новую строку, которая отображает статус обработки как «Обновить».

Как я могу написать запрос оракула для поиска статуса «Ошибка», но вернуть, если что-то было «Обновить»?

Логика будет состоять в том, чтобы выбрать все данные с ошибкой, если для того же статуса Process_ID установлено значение «Обновить», тогда выберите только обновление.

Например, вот некоторые примеры данных о том, как это выглядит, я хочу вернуть только строки 2, 4, 6 и 7

+------+---------+-------------+
|Row_ID|ProcessID|ProcessStatus|
+------+---------+-------------+
|1     |123      |Error        |
|2     |123      |Refresh      | 
|3     |456      |Error        |
|4     |456      |Refresh      | 
|5     |789      |Error        |
|6     |789      |Refresh      | 
|7     |987      |Error        |
+------+---------+-------------+

Ответы [ 3 ]

0 голосов
/ 08 мая 2019

Если большие значения row_id означают более новые записи, вам нужно только получить максимум row_id для каждого processid и затем присоединиться к таблице:

select t.*
from tablename t inner join (
  select processid, max(row_id) row_id
  from tablename
  group by processid
) g on t.row_id = g.row_id
0 голосов
/ 08 мая 2019

Если существует не более двух определенных опций (а именно Error и Refresh) для ProcessStatus, просто используйте следующее с оператором in

select *
  from tab 
 where ( ProcessID, ProcessStatus ) in
  (
   select ProcessID, max(ProcessStatus)
     from tab
    group by ProcessID
  )
 order by row_id;

Демо

0 голосов
/ 08 мая 2019

Exists приходит на ум:

select t.*
from t
where t.processstatus = 'Refresh' and
      exists (select 1 
              from t t2
              where t2.ProcessID = t.ProcessID and t2.processstatus = 'Error'
             )
union all
select t.*
from t
where t.processstatus = 'Error' and
      not exists (select 1 
                  from t t2
                  where t2.ProcessID = t.ProcessID and t2.processstatus = 'Refresh'
                 );

Или вы можете использовать оконные функции:

select t.*
from (select t.*,
             row_number() over (partition by processid
                                order by case processstatus when 'Refresh' then 1 else 2 end
                               ) as seqnum,
             sum(case when processstatus = 'Error' then 1 else 0 end) over (partition by processid) as cnt_error
      from t
     ) t
where seqnum = 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...