sql - 从 SQL Presto 中的日常字段创建新字段列

标签 sql presto recursive-query

我想根据每天访问的所有访客来计算新访客。目前我唯一可用的数据是前 2 列,因此我需要根据前 2 列推断后 2 列。

<表类=“s-表”> <标题> 日期 今日访客 新访客 All_Visitors_To_Date <正文> 12 月 6 日 艾莉,乔恩 艾莉,乔恩 艾莉,乔恩 12 月 7 日 艾莉、乔恩、扎克 扎克 艾莉、乔恩、扎克 12 月 8 日 倒钩,乔恩 倒钩 艾莉、倒钩、乔恩、扎克 12 月 9 日 珍妮特,扎克 珍妮特 艾莉、巴布、珍妮特、乔恩、扎克

这是我到目前为止创建第一列和第二列的内容

WITH visitor_log_response AS (
    SELECT
        CAST(JSON_PARSE(visitor_log) AS MAP<VARCHAR, VARCHAR>) AS visitor_map,
        date
    FROM visitor_log_response_table
),
names_and_dates AS (
    SELECT DISTINCT
        visitor_name AS visitor_name,
        date
    FROM visitor_log_response 
    CROSS JOIN UNNEST(visitor_map) AS u(visitor_name, visitor_age)
),
visitor_names AS (
    SELECT
        date,
        ARRAY_JOIN(
            ARRAY_AGG(
                visitor_name
                ORDER BY
                    visitor_name
            ),
            ','
        ) visitors_today,
    FROM names_and_dates
    GROUP BY
        date
    ORDER BY
        date DESC
)
SELECT
    date,
    visitors_today
FROM visitor_names

结果是这样的

<表类=“s-表”> <标题> 日期 今日访客 <正文> 12 月 6 日 艾莉,乔恩 12 月 7 日 艾莉、乔恩、扎克 12 月 8 日 倒钩,乔恩 12 月 9 日 珍妮特,扎克

如果使用此查询对表进行规范化

SELECT ds, visitors_today_split
FROM previous_table
CROSS JOIN UNNEST(SPLIT(visitors_today),',')) as (visitors_today_split)

我会得到这个输出

<表类=“s-表”> <标题> 日期 今日访客 <正文> 12 月 6 日 艾莉 12 月 6 日 乔恩 12 月 7 日 艾莉 12 月 7 日 乔恩 12 月 7 日 扎克 12 月 8 日 倒钩 12 月 8 日 乔恩 12 月 9 日 珍妮特 12 月 9 日 扎克

最佳答案

您可以使用window functions使用数组聚合(从 ARRAY_JOIN CTE 中删除 visitor_names):

-- sample data
with dataset(date, visitors_today) as (
    values ('Dec 6', array['Allie', 'Jon']),
        ('Dec 7', array['Allie', 'Jon', 'Zach']),
        ('Dec 8', array['Barb', 'Jon']),
        ('Dec 9', array['Janet', 'Zach'])
)

-- query
select date,
    visitors_today,
    array_distinct(visitors_today || prev_visitors) all_visitors_to_date,
    array_except(visitors_today, prev_visitors) new_visitors    
from (
    select *,
           coalesce(
                flatten(array_distinct(array_agg(visitors_today)
                    over (order by date rows between UNBOUNDED PRECEDING and 1 PRECEDING))),
                array[]) as prev_visitors  -- combine all visitors before today into non null array
    from dataset);

输出:

<表类=“s-表”> <标题> 日期 今天的visitors all_visitors_to_date 新访客 <正文> 12 月 6 日 [艾莉,乔恩] [艾莉,乔恩] [艾莉,乔恩] 12 月 7 日 [艾莉、乔恩、扎克] [艾莉、乔恩、扎克] [扎克] 12 月 8 日 [倒钩,乔恩] [倒钩、乔恩、艾莉、扎克] [倒钩] 12 月 9 日 [珍妮特,扎克] [珍妮特、扎克、艾莉、乔恩、倒钩] [珍妮特]

请注意,就性能而言,数组可能不是最佳类型,并且在 Presto/Trino 中仅限于 10000 个元素。

关于sql - 从 SQL Presto 中的日常字段创建新字段列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74777204/

相关文章:

mysql多group_concat顺序保存

sql - 从 prestodb 中选择多个列的不同列

mysql - 如何根据先前和最后更改的值构建新的日期列?

sql - 如何从 TRINO 中的键/值对象数组中提取值并创建逗号分隔的值数组

sql - 使用递归查询构建表依赖关系图

SQL Server 2008 R2 - 递归 SQL - 这可能吗?

mysql - 从具有特定根的 SQL 表中获取最新分支的最有效方法是什么?

在 Power BI 中运行时 SQL 报告无效语法

sql - 根据可变长度字段将列分成两部分

sql - 如何限制 MERGE 语句中 OUTPUT 子句的操作?