0

私たちのプラットフォームの 1 日の平均ユーザー数を知りたいです。制限は、BigQuery 用の SQL を作成する BI ツール (Looker) にこれを実装する必要があることです。そのため、select ステートメントにカスタム SQL コードを入れることしかできず、任意にクエリを作成することはできません。

少量のデータで機能するソリューションを見つけましたが、それを拡張すると、配列の 100MB のハード リミットでエラーがスローされます。

連結と分割は、配列のサイズを小さくすることです。最初に STRUCT(id, date) を使用しましたが、STRUCT で DISTINCT を使用することはできません。

ファイルサイズの問題は関数内には表示されず、ARRAY_AGG(

CREATE TEMP FUNCTION trend_daily_avg(columns_arr ARRAY<STRING>) AS ((
    SELECT AVG(value)
    FROM (
        SELECT
            COUNT(DISTINCT columns_arr.value_column) as value,
        FROM (
            SELECT
                SPLIT(concatstring, " ")[SAFE_OFFSET(1)] as value_column,
                SPLIT(concatstring, " ")[SAFE_OFFSET(0)] as time_column,
            FROM UNNEST(columns_arr) concatstring
        ) columns_arr
        GROUP BY columns_arr.time_column
    )
));
WITH dummy_data as (
    SELECT "10-10-2021" as view_date, 0001 as full_visitor_id, "group-1" as hostname UNION ALL 
    SELECT "10-10-2021" as view_date, 0002 as full_visitor_id, "group-1" as hostname UNION ALL 
    SELECT "10-10-2021" as view_date, 0001 as full_visitor_id, "group-1" as hostname UNION ALL 
    SELECT "11-10-2021" as view_date, 0002 as full_visitor_id, "group-2" as hostname UNION ALL 
    SELECT "11-10-2021" as view_date, 0003 as full_visitor_id, "group-2" as hostname UNION ALL 
    SELECT "11-10-2021" as view_date, 0001 as full_visitor_id, "group-1" as hostname UNION ALL 
    SELECT "12-10-2021" as view_date, 0002 as full_visitor_id, "group-2" as hostname UNION ALL 
    SELECT "12-10-2021" as view_date, 0002 as full_visitor_id, "group-2" as hostname
)
SELECT
    hostname,
    count(distinct full_visitor_id) as users_dedup,
    trend_daily_avg(ARRAY_AGG( DISTINCT
        CONCAT(view_date, " ", full_visitor_id) IGNORE NULLS
    )) as average_trend, # This works for a small amount of data but not in production
    ARRAY_AGG( DISTINCT
        CONCAT(view_date, " ", full_visitor_id) IGNORE NULLS
    ) as average_trend, # This also doesnt work, the upper query fails at this part
FROM ( # Subselect cannot be touched as it cannot be integrated into the BI tool
    SELECT
        view_date,
        full_visitor_id,
        hostname, # More dimensions get dynamically added and then grouped
    FROM dummy_data
)
GROUP BY hostname;

どうにかして BigQuery の最大行サイズを増やすか、大量の配列を作成する必要がないようにクエリを書き直すことはできますか?

編集:機能する1つの解決策は、毎日(日の粒度の場合)または月(月の粒度の場合)を別々に配列に追加することです。これは間違いなく理想的なソリューションではなく、非常に非効率的ですが、機能します。これをより効率的にする方法はありますか?1 か月の日付と ID だけで約 30 GB のデータがあり、3 年間の範囲で最大 1000 のサブクエリがあるのはかなり悪いことです。

CREATE TEMP FUNCTION avg_array(arr ANY TYPE) AS ((
    SELECT 
        AVG(val) 
    FROM(
        SELECT val 
        FROM UNNEST(arr) val 
        where val > 0
    )
)
);
 
select
count(distinct id) as users_dedup,
avg_array([
    count(distinct case when day = '2021-01-01' then id else null end),
    count(distinct case when day = '2021-02-01' then id else null end),
    count(distinct case when day = '2021-03-01' then id else null end),
    count(distinct case when day = '2021-04-01' then id else null end),
    count(distinct case when day = '2021-05-01' then id else null end),
    count(distinct case when day = '2021-06-01' then id else null end),
    count(distinct case when day = '2021-07-01' then id else null end),
    count(distinct case when day = '2021-08-01' then id else null end),
    count(distinct case when day = '2021-09-01' then id else null end),
    count(distinct case when day = '2021-10-01' then id else null end),
    count(distinct case when day = '2021-11-01' then id else null end),
    count(distinct case when day = '2021-12-01' then id else null end)
]) as avg_monthly_users 

from (
select '123' as id, '2021-01-01' as day
union all
select '456' as id, '2021-02-01' as day
union all
select '123' as id, '2021-03-01' as day
)
4

1 に答える 1