oracle получает количество игроков по дате их входа в систему

#oracle #row #next #lead

Вопрос:

У меня есть таблица игроков в качестве игрока 1, где я хочу получить количество людей, которые вошли в систему второй день подряд. Так что в моем случае результат будет 2, так как 2 человека вошли в систему второй день подряд. Я попробовал следующее выбрать количество(*) из ( выберите идентификатор игрока из группы player1 по идентификатору игрока, у которого количество(идентификатор игрока)>1 по идентификатору игрока ) присоединиться к игроку 1 b на.идентификатор игрока=b.идентификатор игрока и b.дата входа в систему (b.дата входа в систему, (b.дата входа в систему 1))

Но это касается всех строк, то есть 9 строк

введите описание изображения здесь

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

1. Ваши примерные данные не имеют смысла. В некоторых строках ИДЕНТИФИКАТОР игрока = 3 имеет ИМЯ = Джейк, в других тот же идентификатор имеет ИМЯ = Джон. Тогда почему вы не хотите, чтобы что-то возвращалось для последних двух строк в таблице? Идентификатор ИГРОКА = 4 вошел в систему 11/1 и 11/2 дней подряд. Наконец, для уточнения: если один и тот же игрок входит в систему в последовательные дни более одного раза (скажем, 8/20 и 8/21, а затем также один и тот же игрок, 9/03 и 9/04), хотите ли вы считать каждое событие отдельно или это просто 1 (для «отдельного игрока, который вошел в систему в последовательные дни один раз или, возможно, более одного раза»)?

2. Извините, что я экспериментировал, вот почему я столкнулся с этой проблемой. Я отредактировал свой вопрос, пожалуйста, помогите, когда у вас будет возможность

3. Я хотел ,чтобы результат был таким, как 2, поскольку 2 человека в таблице вошли в систему последовательно в течение нескольких дней с самой ранней даты их входа в систему, другие вошли в систему, но не в течение нескольких дней с самой ранней даты их входа в систему

4. … но теперь (после изменения ваших выборочных данных) у вас есть игроки, которые вошли в систему в один и тот же день — действительно ли это возможно в ваших реальных данных? И если да, то считается ли это «вторым входом в систему», или это должно быть в разные дни — в самый ранний день и на следующий день? Обратите внимание, что в исходном сообщении и в измененном вы нигде не упоминали, что последовательные входы в систему должны включать самую раннюю дату.

5. Нет, я намеренно вошел в dups, но хочу только подсчитать игроков, имеющих самую раннюю дату 1 в данных, мог бы найти решение, как показано ниже, пожалуйста, дайте мне знать, если есть какой-либо другой способ его достижения

Ответ №1:

В Oracle 12 и выше вы можете легко сделать это с помощью match_recognize :

 select count(*)
from   player1
match_recognize(
  partition by player_id
  order     by log_in_date
  pattern   (^ first_date same_day* next_day)
  define    next_day as log_in_date = first_date.log_in_date   1
);
 

Имена в pattern предложении (и в define ) предоставляются по нашему усмотрению (мы создаем эти имена так же, как мы можем давать псевдонимы таблицам или столбцам в запросе). Они используются для классификации строк — либо как «first_date», «same_day» (как первая дата), либо «next_day» (после начальной даты входа в систему). Привязка ^ означает, что совпадение начнется с самой ранней даты в каждом разделе (это используется точно так же, как и в регулярных выражениях для строк).

match_recognize обучение требует времени (для программистов, которые еще не знают и не используют его), но оно того стоит.

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

1. Спасибо за ваш ответ, но, к сожалению, у меня есть только 11g

Ответ №2:

Я смог получить ответ, как показано ниже:

 select count(distinct dt) from (
  select player_id, min(log_in_date)   1 dt
  from player1
  group by player_id 
  having count(player_id) > 1
) A join player1
on player1.player_id = a.player_id
where player1.log_in_date = dt
 

Есть ли более простой способ сделать это? Пожалуйста, дайте мне знать.

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

1. Выберите код, который вы опубликовали. Затем либо нажмите CTRL-K на клавиатуре, либо нажмите кнопку {} форматирования вверху. И то, и другое приведет к тому, что код будет отформатирован как код.