代码之家  ›  专栏  ›  技术社区  ›  alvas

如何在SQL中使用通过group by聚合的日期“create table as”?

  •  0
  • alvas  · 技术社区  · 5 年前

    给定一个如下所示的数据,其中日期为字符串格式 YYYYMMDD :

    项目 越南人 费用 唯一id 销售日期
    水果 特雷礁 10 abc123 20211001
    水果 特雷礁 8. foo99 20211001
    水果 特雷礁 9 foo99 20211001
    蔬菜 劳 3. rr1239 20211001
    蔬菜 劳 3. rr1239 20211001
    水果 特雷礁 12 abc123 20211002
    水果 特雷礁 14 abc123 20211002
    水果 特雷礁 8. abc123 20211002
    水果 特雷礁 5. foo99 20211002
    蔬菜 劳 8. rr1239 20211002
    蔬菜 劳 1. rr1239 20211002
    蔬菜 劳 12 ud9213 20211002
    蔬菜 劳 19 r11759 20211002
    水果 特雷礁 6. foo99 20211003
    水果 特雷礁 2. abc123 20211003
    水果 特雷礁 12 abc123 20211003
    蔬菜 劳 1. ud97863 20211003
    蔬菜 劳 9 r112359 20211003
    水果 特雷礁 6. foo99 20211004
    水果 特雷礁 2. abc123 20211004
    水果 特雷礁 12 abc123 20211004
    蔬菜 劳 9 r112359 20211004

    目标是

    • 每行最多选择N行 sales_date 具体时间范围
    • 使用 group by 在“项目”列中,

    e、 g.在“20211002”和“20211004”之间,每天最多3行:

    SELECT *
    FROM 
        (SELECT item, 
                max(vietnamese) as vietnamese,
                sum(cost) as total_cost,
                array_agg(cost) as costs,
                array_agg(unique_id) as unique_ids,
                row_number() over (partition by max(sales_date) order by rand()) as row
         FROM mytable
         where sales_date between '20211002' and '20211004'
      GROUP BY item)
    where row <= 3
    limit 9
    

    注: vietnamese 每列 item 是一对一的映射,因此 max(vietnamese)

    上述结果应类似于:

    项目 越南人 成本 唯一标识
    水果 特雷礁 [8] [abc123]
    蔬菜 劳 [8, 1] [rr1239,rr1239]
    水果 特雷礁 [2, 12] [abc123,abc123]
    蔬菜 劳 [1] [ud97863]
    水果 特雷礁 [6, 2, 12] [foo99,abc123,abc123]

    所需的输出被保存为 parquet 格式:

    项目 越南人 成本 唯一标识 销售日期
    水果 特雷礁 [8] [abc123] 20211002
    蔬菜 劳 [8, 1] [rr1239,rr1239] 20211002
    水果 特雷礁 [2, 12] [abc123,abc123] 20211003
    蔬菜 劳 [1] [ud97863] 20211003
    水果 特雷礁 [6, 2, 12] [foo99,abc123,abc123] 20211004

    目的是把它保存到 s3://somes3path/ ,目录中有一些结构:

    s3://somes3path/
         item=fruits/
            sales_date=20211002
            sales_date=20211003
         item=vege/
            sales_date=20211002
            sales_date=20211003
            sales_date=20211004
    

    如何在abvoe所列的目录结构中实现预期的输出?


    我尝试过这个方法,但没有像我预期的那样将其保存在正确的目录结构中:

    CREATE TABLE somedb.mytable
    WITH ( format = 'PARQUET', external_location = 's3://somes3path/', 
           partitioned_by = ARRAY['item'], 
           bucketed_by = ARRAY['sales_date'], bucket_count = 30) AS 
    SELECT *
    FROM 
        (SELECT item, 
                max(vietnamese) as vietnamese,
                sum(cost) as total_cost,
                array_agg(cost) as costs,
                array_agg(unique_id) as unique_ids,
                first(sales_date) as sales_date,
                row_number() over (partition by max(sales_date) order by rand()) as row
         FROM mytable
         where sales_date between '20211002' and '20211004'
      GROUP BY item)
    where row <= 3
    limit 9
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   Theo    5 年前

    您的输出仅按 item ,如果您将其更改为按分区 项目 和 sales_date 您将获得所需的目录结构。移除扣环,因为它不会对分区产生任何影响 销售日期 :

    WITH (
      format = 'PARQUET',
      external_location = 's3://somes3path/', 
      partitioned_by = ARRAY['item', 'sales_date']
    )