PARTITION BY в CASE не работает с несколькими операторами AND - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть таблица с 4 столбцами: hitId, userId, timestamp и Camp.Мне нужно классифицировать, является ли попадание началом новой сессии или нет (1 или 0), используя два параметра: 1. разницу во времени между попаданиями и 2. если источником попадания является новая кампания.

Мне нужен стандартный запрос SQL в BigQuery.

Хит считается началом нового сеанса, если выполняется одно из следующих условий:

  1. это первое попадание изего userId
  2. разница во времени между отметкой времени предыдущего попадания из того же userId составляет более 30 минут.
  3. разница во времени между отметкой времени предыдущего попадания из того же userId меньшечем 30 минут, но значение Camp (рекламная кампания) не равно NULL и встречается в первый раз для того же идентификатора пользователя в течение предыдущих 30 минут.

Так что, если хит1 из user1 имеет Camp, равный Campaign1и hit2 от user1 имеет Camp, равный Campaign1, а разница во времени между hit1 и hit2 составляет менее 30 минут, hit1 будет рассматриваться как начало сеанса, а hit2 не будет рассматриватьсядля начала.

У меня проблемы с частью кампании.Я пробовал этот код:

Я пробовал этот код:

WITH timeDifference AS (
  SELECT *, 
  TIMESTAMP_DIFF(timestamp, LAG(timestamp, 1) OVER
          (PARTITION BY userId ORDER BY timestamp), SECOND) AS difference
    FROM hitTable
      ORDER BY timestamp)
SELECT *, 
  CASE 
  WHEN difference >= 30 * 60 THEN 1 
  WHEN difference IS NULL THEN 1 
  WHEN difference <= 30 * 60 AND Camp IS NOT NULL AND RANK() 
  OVER (PARTITION BY userId ORDER BY Camp) = 1 THEN 1
  ELSE 0 END AS sess
  FROM timeDifference
  ORDER BY timestamp;

Условие RANK() OVER (PARTITION BY userId ORDER BY Camp), кажется, не работает, так как я получаю эту таблицу:

hitId | userId |  timestamp   |  Camp           |  difference  |  sess
_______________________________________________________________________
00150 | 858201 | 00:48:35.315 |  NULL           |  NULL        |  1
00151 | 858201 | 00:49:35.315 |  NULL           |  5           |  0
00152 | 858201 | 00:50:35.315 |  Search-Ads-US  |  10          |  0
00153 | 858201 | 00:53:35.315 |  Search-Ads-US  |  15          |  0
00154 | 858202 | 00:54:35.315 |  Facebook-Ads   |  NULL        |  1
00155 | 858202 | 00:54:55.315 |  Facebook-Ads   |  9           |  0
00156 | 858202 | 00:57:20.315 |  Facebook-Ads   |  12          |  0

ПокаЯ ожидаю иметь 1 для sess столбца для hitId = 00152:

hitId | userId |  timestamp   |  Camp           |  difference  |  sess
_______________________________________________________________________
00150 | 858201 | 00:48:35.315 |  NULL           |  NULL        |  1
00151 | 858201 | 00:49:35.315 |  NULL           |  5           |  0
00152 | 858201 | 00:50:35.315 |  Search-Ads-US  |  10          |  1
00153 | 858201 | 00:53:35.315 |  Search-Ads-US  |  15          |  0
00154 | 858202 | 00:54:35.315 |  Facebook-Ads   |  NULL        |  1
00155 | 858202 | 00:54:55.315 |  Facebook-Ads   |  9           |  0
00156 | 858202 | 00:57:20.315 |  Facebook-Ads   |  12          |  0

1 Ответ

0 голосов
/ 13 декабря 2018

Этот RANK () OVER (PARTITION BY userId ORDER BY Camp) возвращает ложные результаты в случаях, когда у пользователя было несколько Camps.

Обратите внимание, что ваш PARTITION BY использует userId, когда вы хотите отмечать сессии в каждом Camp.

Фактический «ранг 1» оператора RANK () (...) для userId 00150 - это когда Camp имеет значение NULL (hitId 00150), поэтому он пропускает условие CASE в hitId 00152.

Вы можете попытаться добавить 'Camp' к вашему PARTITION BY следующим образом: RANK () OVER (PARTITION BY userId, Camp ORDER BY Camp)

В качестве альтернативы, вы можете заменить RANK () (...) и использовать LAG (Camp) (... упорядочить по метке времени) в дополнение к LAG (временная метка) (...), которую вы вычисляете.Это извлечет значение Camp для строки перед этим (назовите его «PreviousCampValue»).Тогда вы можете добавить что-то вроде WHEN PreviousCampValue! = Camp THEN 1

Надеюсь, что это полезно

...