SQL, сравнивающий два результата по строкам с похожими идентификаторами

#sql

#sql

Вопрос:

Допустим, моя таблица выглядит примерно так

 id | can_id | last_touch | result
1  | 1001   | 2017-05-01 | good
2  | 1001   | 2017-07-01 | bad
3  | 1002   | 2018-01-01 | good
4  | 1003   | 2019-02-08 | bad
  

Я хочу создать поиск, который найдет строки, которые проверят, соответствует ли последняя last_touch дата good

Как мне выполнить «цикл» по каждой из них cand_id в поиске, чтобы найти самую последнюю last_touch дату и строки result и вернуть, если good ?

Комментарии:

1. можете ли вы пометить используемую СУБД и показать ожидаемый результат?

Ответ №1:

Вам нужен коррелированный подзапрос :

 select t.*, 
       (case when t.result = 'good' then 'yes' else 'no' end) as is_good
from table t
where t.last_touch = (select max(t1.last_touch) from table t1 where t1.can_id = t.can_id);
  

Однако, то же самое вы также можете использовать row_number() :

 select t.*,
       (case when t.result = 'good' then 'yes' else 'no' end) as is_good
from (select t.*,
             row_number() over (partition by t.can_id order by t.last_touch desc) as seq
      from table t
     ) t
where seq = 1;
  

Ответ №2:

Вы можете использовать коррелированный подзапрос:

 select t.*,
       (case when result = 'good' then 1 else 0 end) as is_good
from t
where t.last_touch = (select max(t2.last_touch)
                      from t t2
                      where t2.can_id = t.can_id
                     ) ;
  

Или, если вам нужны только строки, где last_touch есть 'good' , добавьте and предложение result = ‘good’ to the where`.

Из вашего вопроса трудно сказать, нужен ли вам флаг или фильтр.

Комментарии:

1. на самом деле, работает любой из них. Меньше о конкретном ответе и больше о том, что я должен исследовать 🙂 Это здорово. Спасибо