Условие
Выгрузить игроков, которые с 12:00 14.03.2022 сделали ставку в пре-матч на события раздела «Киберспорт». Условия Бонусного предложения:
- Минимальная сумма ставки — 10 BYN.
- Коэффициент в одиночке ≥ 1.5; в экспрессе на киберспорт — каждый исход с к-ом ≥ 1.5.
- Ставка должна быть рассчитана не позднее 12:00 15.03.2022.
- Ставки вида «система» не учитываются.
- CashOut, возвраты и FreeBet не участвуют.
Решение
Подход
Достаточно одного запроса с WHERE, агрегирующим суммы ставок по игроку, плюс HAVING на сумму. Допущение по схеме: есть таблица bets(user_id, bet_id, bet_type, stake, status, settle_time, created_time) и bet_legs(bet_id, sport, market_type, odds).
Реализация
WITH eligible_bets AS (
SELECT b.bet_id, b.user_id, b.stake
FROM bets b
WHERE b.created_time >= TIMESTAMP '2022-03-14 12:00'
AND b.settle_time <= TIMESTAMP '2022-03-15 12:00'
AND b.bet_type IN ('single','express') -- без 'system'
AND b.is_freebet = FALSE
AND b.is_cashout = FALSE
AND b.status NOT IN ('return','void')
AND b.stake >= 10
-- Все ноги — киберспорт, пре-матч, к ≥ 1.5
AND NOT EXISTS (
SELECT 1
FROM bet_legs l
WHERE l.bet_id = b.bet_id
AND (l.sport <> 'esports'
OR l.market_type <> 'prematch'
OR l.odds < 1.5)
)
)
SELECT DISTINCT user_id
FROM eligible_bets;Python-аналог
mask = (
df.created_time >= "2022-03-14 12:00"
) & (df.settle_time <= "2022-03-15 12:00") & (df.stake >= 10) & \
(df.bet_type.isin(["single","express"])) & (~df.is_freebet) & (~df.is_cashout)
bad = legs[(legs.sport != "esports") | (legs.market_type != "prematch") | (legs.odds < 1.5)]
df = df[mask & ~df.bet_id.isin(bad.bet_id.unique())]
print(df.user_id.unique())Подводные камни
- «Все ноги ≥ 1.5» — проверяется через
NOT EXISTSноги сodds < 1.5. Иначе для одиночек с одной ногой условие тривиально, но для экспресса нужно именно «во всех ногах». - Часовой пояс:
12:00 14.03локально — уточнить TZ в данных. - Возвраты могут быть зашиты в
statusили в отдельный флаг — проверить схему. - CashOut обычно фиксируется отдельной строкой с уменьшенной суммой; считать стоит исходную ставку.
Эталонный ответ
Фильтр по времени, типу ставки, отсутствию ноги вне киберспорта/прематча/к<1.5, минимальной сумме — затем DISTINCT user_id.