Пример соответствующей схемы таблицы:
+---------------------------+-------------------+
| activity_date - TIMESTAMP | user_id - STRING |
+---------------------------+-------------------+
| 2017-02-22 17:36:08 UTC | fake_id_i24385787 |
+---------------------------+-------------------+
| 2017-02-22 04:27:08 UTC | fake_id_234885747 |
+---------------------------+-------------------+
| 2017-02-22 08:36:08 UTC | fake_id_i24385787 |
+---------------------------+-------------------+
Мне нужно подсчитывать активных отдельных пользователей по большому набору данных в течение скользящего периода времени (90 дней), и я сталкиваюсь с проблемами из-за размеранабор данных.
Сначала я попытался использовать оконную функцию, подобную ответу здесь.https://stackoverflow.com/a/27574474
WITH
daily AS (
SELECT
DATE(activity_date) day,
user_id
FROM
`fake-table`)
SELECT
day,
SUM(APPROX_COUNT_DISTINCT(user_id)) OVER (ORDER BY day ROWS BETWEEN 89 PRECEDING AND CURRENT ROW) ninty_day_window_apprx
FROM
daily
GROUP BY
1
ORDER BY
1 DESC
Однако это привело к получению различного числа пользователей в день, а затем суммированию их - но различия могут дублироваться в окне, если они появляются несколько раз.Так что это не совсем точный показатель для отдельных пользователей за 90 дней.
Следующее, что я попробовал, - это использовать следующее решение https://stackoverflow.com/a/47659590 - объединение всех отдельных user_ids для каждого окна в массиви затем подсчитываем различия в этом.
WITH daily AS (
SELECT date(activity_date) day, STRING_AGG(DISTINCT user_id) users
FROM `fake-table`
GROUP BY day
), temp2 AS (
SELECT
day,
STRING_AGG(users) OVER(ORDER BY UNIX_DATE(day) RANGE BETWEEN 89 PRECEDING AND CURRENT ROW) users
FROM daily
)
SELECT day,
(SELECT APPROX_COUNT_DISTINCT(id) FROM UNNEST(SPLIT(users)) AS id) Unique90Days
FROM temp2
order by 1 desc
Однако это быстро исчерпало память с чем-либо большим.
Далее было использовать эскиз HLL для представления различных идентификаторов в гораздо меньшем размере.значение, поэтому память будет меньше проблем.Я думал, что мои проблемы были решены, но я получаю сообщение об ошибке при выполнении следующего: Ошибка просто «Функция MERGE_PARTIAL не поддерживается».Я тоже попробовал с MERGE и получил ту же ошибку.Это происходит только при использовании оконной функции.Создание эскизов для ценности каждого дня прекрасно работает.
Я прочитал документацию по BigQuery Standard SQL и не вижу ничего о HLL_COUNT.MERGE_PARTIAL и HLL_COUNT.MERGE с оконными функциями.Предположительно, это должно взять 90 эскизов и объединить их в один эскиз HLL, представляющий различные значения между 90 исходными эскизами?
WITH
daily AS (
SELECT
DATE(activity_date) day,
HLL_COUNT.INIT(user_id) sketch
FROM
`fake-table`
GROUP BY
1
ORDER BY
1 DESC),
rolling AS (
SELECT
day,
HLL_COUNT.MERGE_PARTIAL(sketch) OVER (ORDER BY UNIX_DATE(day) RANGE BETWEEN 89 PRECEDING AND CURRENT ROW) rolling_sketch
FROM daily)
SELECT
day,
HLL_COUNT.EXTRACT(rolling_sketch)
FROM
rolling
ORDER BY
1
«Изображение ошибки - функция MERGE_PARTIAL не поддерживается»
Есть идеи, почему возникает эта ошибка или как ее исправить?