Удержание дня N в BigQuery, сообщение об ошибке: Неверный часовой пояс - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь рассчитать срок хранения N для набора данных в Google Big Query. Таблица состоит из одного месяца данных из мобильного приложения, и я хочу узнать, сколько пользователей возвращалось каждый день. Я использую StandardSQL. Пока код у меня есть

SELECT date(d1.eventDate) as dt,
        COUNT(distinct d1.userID) as total_users,
        COUNT(distinct d2.userID) as retained_users
         FROM `dataset` as d1
        LEFT JOIN `dataset` as d2 ON 
        d1.userID = d2.userID
        AND date(d1.eventDate) = date(datetime(d2.eventDate, '-1 day'))
          GROUP BY 1
          ORDER BY 1"

Когда я пытаюсь выполнить, я получаю сообщение об ошибке

  Error: Invalid time zone: -1 day [invalidQuery]

Моя структура таблицы

    eventDate           | UserID | 
2016-05-06 00:00:00 UTC | 100000 |
2016-05-06 00:00:00 UTC | 200000 |
2016-05-06 00:00:00 UTC | 300000 |

Что я должен использовать вместо «-1 день»?

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Ниже для BigQuery Standard SQL и дополнительно оптимизирован для того, чтобы не использовать какие-либо JOIN, а использовать аналитические функции

#standardSQL
SELECT
  day, 
  COUNT(1) total_users,
  COUNTIF(delta = 1) retained_users
FROM (
  SELECT
    day, id, 
    DATE_DIFF(day, LAG(day) OVER(PARTITION BY id ORDER BY day), DAY) delta
  FROM (
    SELECT DISTINCT
      DATE(created_at) day,
      actor.id
    FROM `githubarchive.month.201810`
  )
)
GROUP BY day
ORDER BY day   

или, если использовать исходную запись вопроса:

#standardSQL
SELECT
  day, 
  COUNT(1) total_users,
  COUNTIF(delta = 1) retained_users
FROM (
  SELECT
    day, userID, 
    DATE_DIFF(day, LAG(day) OVER(PARTITION BY userID ORDER BY day), DAY) delta
  FROM (
    SELECT DISTINCT
      DATE(eventDate) day,
      userID
    FROM `project.dataset.table`
  )
)
GROUP BY day
ORDER BY day
0 голосов
/ 20 ноября 2018

TIMESTAMP_SUB исправит запрос в письменном виде, но может оказаться недостаточно хорошим решением для повышения производительности. Но, по крайней мере, вы получите 1 день вычитания:

SELECT date(d1.created_at) as dt,
        COUNT(distinct d1.actor.id) as total_users,
        COUNT(distinct d2.actor.id) as retained_users
         FROM `githubarchive.month.201810` as d1
        LEFT JOIN `githubarchive.month.201810` as d2 ON 
        d1.actor.id = d2.actor.id
        AND date(d1.created_at) = date(TIMESTAMP_SUB(d2.created_at, INTERVAL -24 HOUR))
          GROUP BY 1
          ORDER BY 1

Чтобы улучшить производительность, выполните дедупликацию перед JOIN:

SELECT day as dt,
    COUNT(distinct d1.id) as total_users,
    COUNT(distinct d2.id) as retained_users
FROM (SELECT DISTINCT actor.id, DATE(created_at) day FROM `githubarchive.month.201810`)as d1
LEFT JOIN (SELECT DISTINCT actor.id,  DATE(TIMESTAMP_SUB(created_at, INTERVAL -24 HOUR)) day FROM `githubarchive.month.201810`) as d2 
USING (id, day)
GROUP BY 1
ORDER BY 1

enter image description here

...