在数据库的dplyr过滤器函数中传递SQL函数

Zhe*_*ang 2 sql postgresql r dplyr

我正在使用dplyr自动SQL后端从数据库表中查询子表.例如

my_tbl <- tbl(my_db, "my_table")
Run Code Online (Sandbox Code Playgroud)

其中,my_table在数据库中的样子

batch_name    value
batch_A_1     1
batch_A_2     2
batch_A_2     3
batch_B_1     8
batch_B_2     9
...
Run Code Online (Sandbox Code Playgroud)

batch_A_#无论数字如何,我只想要数据.

如果我在SQL中写这个,我可以使用

select * where batch_name like 'batch_A_%'
Run Code Online (Sandbox Code Playgroud)

如果我是在R写入这一点,我可以用一些方法来得到这样的:grepl(),%in%str_detect()

# option 1
subtable <- my_tbl %>% select(batch_name, value) %>%
    filter(grepl('batch_A_', batch_name, fixed = T))
# option 2
subtable <- my_tbl %>% select(batch_name, value) %>%
    filter(str_detect(batch_name, 'batch_A_'))
Run Code Online (Sandbox Code Playgroud)

所有这些都给出了以下Postgres错误: HINT: No function matches the given name and argument types. You might need to add explicit type casts

那么,如何传递SQL字符串函数或匹配函数以帮助使生成的dplyr SQL查询能够使用更灵活的函数范围filter

(仅供参考,该%in%功能确实有效,但需要列出所有可能的值.这可以与paste列表相结合,但不适用于更一般的正则表达式)

dpp*_*dan 6


一个" dplyr唯一"的解决方案就是这样

tbl(my_con, "my_table") %>% 
  filter(batch_name %like% "batch_A_%") %>% 
  collect()
Run Code Online (Sandbox Code Playgroud)

完全代表:

suppressPackageStartupMessages({
  library(dplyr)
  library(dbplyr)
  library(RPostgreSQL)
})

my_con <- 
  dbConnect(
    PostgreSQL(),
    user     = "my_user",
    password = "my_password",
    host     = "my_host",
    dbname   = "my_db"
  )

my_table <- tribble(
  ~batch_name,    ~value,
  "batch_A_1",     1,
  "batch_A_2",     2,
  "batch_A_2",     3,
  "batch_B_1",     8,
  "batch_B_2",     9
)

copy_to(my_con, my_table)

tbl(my_con, "my_table") %>% 
  filter(batch_name %like% "batch_A_%") %>% 
  collect()
#> # A tibble: 3 x 2
#>   batch_name value
#> *      <chr> <dbl>
#> 1  batch_A_1     1
#> 2  batch_A_2     2
#> 3  batch_A_2     3

dbDisconnect(my_con)
#> [1] TRUE
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为dplyr不知道如何翻译的任何函数将按原样传递,请参阅 ?dbplyr::translate\_sql.

帽尖到@PaulRougieux为他最近的评论 点击这里