Это моя входная таблица (таблица игроков) с идентификатором игрока и датами его игры, я хочу, чтобы это сверялось с таблицей вех, в которой есть подробная информация о том, когда игрок достиг своих вех. Я хочу сравнить таблицу вех с таблицей игроков, чтобы узнать, играли ли они в течение 60 дней с даты вехи.
стол игрока
таблица вех
Мой вывод
Как я могу достичь этого
Откуда вывод для игрока 4? Их нет на входе.
веха_дата + 60 дней
теперь я вижу, что в вашем последнем пуле вы говорите «в течение», так что это не совсем 60 дней.
глядя на ваши данные, я не понимаю, почему игрок 4 является «активным игроком»?
Используйте левое соединение для сопоставления игр в течение 60 дней и после 60 дней.
SELECT m.player_id, m.milestone_date,
IF(MAX(c.player_id IS NULL), '60 day churner', 'Active player') AS churn_status,
IF(MAX(r.player_id IS NULL), 'churner', 'returner') AS player_status
FROM milestone AS m
LEFT JOIN player AS c ON c.player_id = m.player_id AND c.date_played > m.milestone_date AND c.date_played <= DATE_ADD(m.milestone_date, INTERVAL 60 DAY)
LEFT JOIN player AS r ON c.player_id = m.player_id AND c.date_played > DATE_ADD(m.milestone_date, INTERVAL 60 DAY)
GROUP BY m.player_id
Это соединяется с player
дважды. Первое соединение получает все строки, в которых воспроизведение происходит между датой вехи и 60 днями позже. Второе соединение получает все строки, в которых происходит воспроизведение через 60 дней.
Если нет совпадений ни для одного из отношений дат, это соединение вернет строку, в которой все столбцы в player
равны NULL
. Условия IF()
проверяют, содержит ли каждое соединение эти нулевые значения, и дают соответствующий результат в этом столбце.
можете ли вы объяснить запрос, пожалуйста
Я добавил объяснение, а также исправил некоторые проблемы.
Похоже, вас интересует только категоризация на основе строк игроков (странное название таблицы, поскольку она, похоже, представляет игры, а не игроков), датированные после даты вехи.
Это довольно просто (непроверено):
select m.player_id, m.milestone_date,
case
when min(p.date_played) <= m.milestone_date + interval 60 day then 'Active player'
else '60 day churner'
end churn_status,
case
when min(p.date_played) is not null then 'returner'
else 'churner'
end player_status
from milestone m
left join player p on p.player_id=m.player_id and p.date_played > m.milestone_date
group by m.player_id
Это находит минимальную дату воспроизведения (если есть) для строк игроков после контрольной даты для каждого игрока и использует ее для определения статусов.
статус игрока возвращается, если он играет в течение 60 дней после контрольной даты.
<= 60 для активного
отредактировано для этого.
и исправил ошибку
Не могли бы вы объяснить свои заявления о случаях, почему MIN?
Как изменить условие, если я хочу сократить 60-дневное окно до 7-14 дней? Ушедшие после достижения вехи за 7-14 дней
min, потому что я присоединяюсь к любым записям игроков для каждого идентификатора игрока вехи и возвращаю одну строку для каждого идентификатора игрока и проверяю минимальную дату воспроизведения, чтобы определить статусы, используя регистр
не уверен, что означает 7-14 дней; игнорировать любые строки менее чем через 7 дней после вехи? если не игнорировать их, то что с ними делать?
На такой вопрос намного легче ответить с помощью правильной схемы, например
SHOW CREATE TABLE
. То, что у вас есть значения в формате M/D/YYYY, безусловно, выделяется, поскольку MySQL имеет тенденцию соответствовать стилюYYYY-MM-DD
ISO.