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

时间:2019-03-25 23:58:17

标签: sql r dplyr tidyverse dbplyr

说我使用dbplyr打开了一个远程tbl,并且我想在上面使用SQL查询(也许是因为我想做的事情没有dbplyr转换),我该如何给出它以便它返回一个远程tbl对象?

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

例如,假设您已经打开了与数据库的连接con,则可以创建如下表:

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()一样),但可以返回一个远程tbl?

谢谢

2 个答案:

答案 0 :(得分:1)

好吧,玩弄它的工作原理,我想我找到了一种方法。您可以在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定义。

答案 1 :(得分:0)

据我了解,有dbplyr从dplyr到SQL的标准翻译的集合。任何超出此翻译范围的内容都将保留。

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

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

并且由于没有从R函数DATEFROMPARTS到SQL函数的定义转换(因为R函数在dplyr中不存在),因此将其保留不变。