Застрял на том, что кажется простой задачей SQL dense_rank

#sql #google-bigquery #rank #dense-rank

#sql #google-bigquery #рейтинг #плотный ранг

Вопрос:

Застрял на этой проблеме и действительно мог бы воспользоваться предложением или помощью.

То, что у меня есть в таблице, является основным потоком пользователей на веб-сайте. Для каждого идентификатора сеанса есть страница, посещенная с начала (попадает на домашнюю страницу) до завершения (покупка). Это было упорядочено по отметке времени, чтобы получить количество страниц, посещенных во время этого процесса. Это «количество страниц» также было разделено по идентификатору сеанса, чтобы возвращаться к 1 при каждом изменении идентификатора.

Что мне нужно сделать сейчас, это назначить количество шагов (выделено то, чего я пытаюсь достичь). Это должно назначить аналогичное количество, но не продолжать подсчет при повторяющихся шагах (т. Е. Кто-то посетил несколько страниц продукта — это несколько страниц, но все еще только один шаг «просмотр продукта».

Можно подумать, что это будет сделано с использованием плотного ранга, разделенного идентификатором сеанса — но вот где я застрял. Вы не можете выполнить заказ по количеству страниц, потому что это присвоит уникальный номер каждому количеству шагов. Вы не можете упорядочивать по шагам, потому что это упорядочивает их в алфавитном порядке.

Что я мог сделать для достижения этого?

Скриншот желаемого результата:

скриншот желаемого результата

Большое спасибо!

Ответ №1:

Используйте lag, чтобы увидеть, совпадают ли два значения, а затем совокупную сумму:

 select t.*,
       sum(case when prev_cs = custom_step then 0 else 1 end) over (partition by session_id order by timestamp) as steps_count
from (select t.*,
             lag(custom_step) over (partition by session_id order by timestamp) as prev_cs
      from t
     ) t
  

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

1. Вы спасаете!

Ответ №2:

Ниже приведен стандартный SQL BigQuery

 #standardSQL
SELECT * EXCEPT(flag), 
  COUNTIF(IFNULL(flag, TRUE)) OVER(PARTITION BY session_id ORDER BY timestamp) AS steps_count
FROM (
  SELECT *,
    custom_step != LAG(custom_step) OVER(PARTITION BY session_id ORDER BY timestamp) AS flag
  FROM `project.dataset.table`
)
-- ORDER BY timestamp