如何给 dplyr 一个 SQL 查询并让它 return 一个远程 tbl 对象?

How to give dplyr a SQL query and have it return a remote tbl object?

假设我有一个使用 dbplyr 打开的远程 tbl,我想对其使用 SQL 查询(可能是因为没有 dbplyr 翻译我想做的事情),我怎么给它这样的它 return 是一个远程 tbl 对象吗?

DBI::dbGetQuery() 函数允许您向 db 查询,但它 return 是内存中的数据帧,而不是远程 tbl 对象。

例如,假设您已经有一个连接 con 打开到一个数据库,您可以像这样创建一个 table:

library(tidyverse)

x_df <- expand.grid(A = c('a','b','c'), B = c('d','e','f', 'g','h')) %>% 
  mutate(C = round(rnorm(15), 2))

DBI::dbWriteTable(conn = con,
                  name = "x_tbl",
                  value = x_df,
                  overwrite = TRUE)

x_tbl = tbl(con, 'x_tbl')

sql_query <- build_sql('SELECT a, b, c, avg(c) OVER (PARTITION BY a) AS mean_c FROM x_tbl')

y_df <- DBI::dbGetQuery(con, sql_query) # This returns a data frame on memory

y_tbl <- x_tbl %>% 
  group_by(a) %>% 
  mutate(mean_c = mean(c))

show_query(y_tbl) # This is a remote tbl object

在这种情况下,我可以使用 y_tbl。但是有些情况下函数没有在dbplyr上翻译(例如分位数不起作用),我需要使用SQL代码。但我不想收集结果,我希望它创建一个远程 tbl 对象。有没有一种方法可以提供 SQL 查询(比如 dbGetQuery()),但有 return 一个远程 tbl?

谢谢

好吧,尝试一下它的工作原理,我想我找到了一种方法。你可以在 mutate 函数中给出一个 sql 查询:

y_tbl <- x_tbl %>% 
  group_by(a) %>% 
  mutate(mean_c = sql("avg(c) OVER (PARTITION BY a)"))

show_query(y_tbl) # This is a remote tbl object

这样您就可以给出变量的 SQL 定义,而不必计算 table。

据我了解,dbplyr 从 dplyr 到 SQL 进行了一系列标准翻译。超出此翻译范围的任何内容均保持原样。

例如,DATEFROMPARTS 是一个 SQL 函数而不是 R 函数。我通常使用以下 mutate:

y_tbl <- x_tbl %>% 
    mutate(new_date = DATEFROMPARTS(year_col, month_col, day_col)

并且因为没有定义从 R 函数 DATEFROMPARTS 到 SQL 函数的转换(因为 dplyr 中不存在 R 函数)所以它保持原样。