【问题标题】:Apply a ranking window function in dbplyr backend在 dbplyr 后端应用排名窗口函数
【发布时间】:2019-08-14 22:04:36
【问题描述】:

我想在我的交易数据库表中无缝识别新订单(收购)和退货。

这听起来像是一个窗口函数的完美工作;我想在dbplyr执行这个操作。

我目前的流程是:

  1. 创建一个查询对象,然后将其用于dbGetQuery();这个查询包含一个标准的rank() 窗口函数,通常在postgresql 中看到
  2. 将此查询引入我的 R 环境中
  3. 然后在mutate() 动词中使用ifelse() 函数,我将第一个订单(又称收购订单)标识为窗口函数标记为1 的订单,否则为“重复”订单。

    query <- 
    "SELECT o.user_id,
    o.id,
    o.completed_at,
    rank() over (partition by o.user_id order by o.completed_at asc) as order_number
    FROM orders as o"
    
     df <- dbGetQuery(db, query) %>%
    mutate(order_type = ifelse(order_number == '1','acquisition','repeat'))
    

我认为有一种方法可以使用 dbplyr 压缩此过程,但目前我不知道具体如何。

这是查询的输出:

    id    user_id completed_at        order_number
1   58051      68 2019-02-02 09:45:59            1
2   78173    7173 2019-03-28 08:30:16            1
3   79585    7173 2019-04-15 21:59:51            2
4  105261    7173 2019-07-15 13:51:44            3
5   57158    7181 2019-01-02 08:30:12            1
6   64316    7185 2019-02-24 14:54:26            1
7   77556    7185 2019-03-26 08:30:26            2
8   91287    7185 2019-04-25 08:30:25            3
9   55781    7191 2018-12-04 09:21:42            1
10  57039    7191 2019-01-01 08:30:11            2
11  55947    7204 2018-12-10 20:56:41            1
12 106126    7204 2019-06-28 15:10:27            2
13 112490    7204 2019-07-19 14:38:16            3
14 112514    7204 2019-07-19 16:24:09            4

您可以在这个 gdoc 中找到测试数据 -> link

【问题讨论】:

    标签: r dplyr window-functions dbplyr


    【解决方案1】:

    dbplyr 只能将有限的一组 R 命令转换为 SQL 命令,这是实现此目的的一个关键挑战。 dplyr 之外的 R 函数不太可能有效地转换为 SQL。

    假设db 是您的数据库连接,我会尝试以下操作:

    # create a local pointer to the database table
    orders <- tbl(db, from = "orders")
    
    # define table using dplyr commands
    df <- orders %>%
      group_by(user_id) %>%
      mutate(order_number = row_number(complete_at)) %>%
      select(user_id, id, completed_at) %>%
      mutate(order_type = ifelse(order_number == 1, 'acquisition', 'repeat'))
    
    # check underlying sql and confirm it is correct
    df %>% show_query()
    
    # load data into local R from database
    df <- collect(df)
    

    根据您的应用程序,您可能更喜欢dense_rank 而不是row_number。我还没有测试任何一个到 sql 的 dbplyr 翻译。只使用我知道在我的研发和数据库环境中工作的操作:

    orders <- tbl(db, from = "orders")
    
    df_acquisition <- orders %>%
      group_by(user_id) %>%
      mutate(tmp = lead(complete_at, 1, order_by = "complete_at")) %>%
      # only the latest record will lack a tmp value
      filter(is.na(tmp)) %>%
      select(user_id, id, completed_at) %>%
      mutate(order_type = 'acquisition')
    

    然后分别创建重复订单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-29
      • 1970-01-01
      • 2016-05-19
      • 1970-01-01
      • 1970-01-01
      • 2017-09-18
      相关资源
      最近更新 更多