Помогите составить запрос на MySql

174
14 сентября 2017, 17:56

Таблица вида:

id___user_id___lender_id___status
1    1         2           P
2    1         3           P
3    1         4           P
4    1         5           P
5    1         6           P
6    1         7           S
7    1         6           P
8    2         1           P
9    2         3           P
10   2         1           S

Необходимо вывести user_id, если у него 5+ неудачных статусов подряд ( status != "S" ) с 4+ разными lender_id.

Результат данного запроса: user_id = 1

Answer 1

На классическом SQL: для всех записей со статусом не S подбираем такие записи у которых user_id совпадает, id больше или равен (т.е. эта же запись), а status то же не S и при этом не существует записей со статусом S у которых user совпадает а id между двумя вышеописанными. После чего записи группируем по id из первой таблицы (все записи идущие без разрывов будут с одним id), считаем и проверяем нужные количества. При этом user_id может дублироваться, если у него окажется несколько участков подходящих под условия, поэтому применяем distinct.

select distinct A.user_id
  from Table1 A
  join Table1 B
    on B.user_id=A.user_id and B.id>=A.id and B.status!='S'
   and not exists(select 1 from Table1 C
                   where C.user_id=A.user_id and C.status='S'
                     and C.id>A.id and C.id<B.id
                 )
 where A.status!='S'
 group by A.id, A.user_id
 having count(1)>=5 and count(distinct B.lender_id)>=4

Пример

С помощью переменных, только для MySQL, работать должен значительно быстрее первого так как за один проход таблицы. Тут мы вводим переменную rank которую увеличиваем на 1 всякий раз когда встречаем запись со статусом S. Таким образом с одинаковым rank может быть только одна запись со статусом S и несколько записей идущие непосредственно за ней с другими статусами. Записи S отбрасываем, считаем оставшиеся записи с одинаковыми rank.

select distinct user_id
  from (
   select user_id, lender_id, status, @rank:=@rank+(status='S') rank
     from Table1 T, (select @rank:=0) i
    order by user_id, id
  ) X
 where status!='S'
 group by user_id, rank
 having count(1)>=5 and count(distinct lender_id)>=4

Пример

READ ALSO
как работать с PHP через gulp + sublime?

как работать с PHP через gulp + sublime?

Настроил под себя gulp и теперь фронтенд вроде идет без проблемКак лучше всего настроить PHP, базу данных, сервер ? Предлагают пользоваться IDE PhpStorm

166
Как правильно настроить url(чпу) на wp?

Как правильно настроить url(чпу) на wp?

Как задать для кастомного post type правильные urlПример: www

134
Объяснение задачи C++ [требует правки]

Объяснение задачи C++ [требует правки]

Создать класс ВЕКТОР, содержащий ссылки на int, количество элементов вектораКласс имеет конструктор без параметров, конструктор копирования

213