r - 是否可以直接在类 tbl_sql(或 tbl_dbi)上运行 SQL 查询?

标签 r dplyr tibble rsqlite dbplyr

示例代码:

library(DBI)
library(RSQLite)

# will require more details (like user, password, host, port, etc.)
con <- dbConnect(RSQLite::SQLite(), ":memory:")
data(USArrests)
dbWriteTable(con, "USArrests", USArrests)
dbListTables(con)

d0 <- tbl(con, "USArrests")
dbGetQuery(d0, "select * from USArrests")
dbGetQuery(d0, "select * from d0")

返回结果:

Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘dbGetQuery’ for signature ‘"tbl_dbi", "character"’

显然我可以在 con 上使用 dbGetQuery,但想知道是否有办法让它直接在 d0 上工作。

谢谢。

最佳答案

一方面,tbl()函数是SELECT * FROM Table类型的SQL语句,它在DBMS上工作并从数据库服务器检索数据它需要一个像collect()这样的pull函数。另一方面,函数 dbGetQuery() 使用 SQL 查询将数据检索到 R session 中。两者都需要连接到服务器和语句,但第一个使用 SQL 翻译创建语句,另一个是编写 SQL 查询的用户。

为了说明这一点,我将在 postgreSQL DBMS 中使用时态表 tmp:

# Example on postgreSQL
library(tidyverse)
library(dbplyr)
library(RPostgreSQL)
library(DBI) # This is loaded with RPostgreSQL package

con <- dbConnect(PostgreSQL(), 
                 dbname="test",
                 host="localhost",
                 port=5432,
                 user="user",
                 password="pass")

将虚拟数据发送到 PostgreSQL 服务器

date <- data_frame(Col1 = c("20180212", "20180213"),
                   Col2 = c("A", "B"))
dbWriteTable(con, "tmp", date, temporary = TRUE)

使用tbl()函数

tbl(con, "tmp") %>% show_query()

#><SQL> 
#>SELECT * 
#>FROM "tmp"

tbl(con, "tmp") %>% 
  mutate(date = to_date(Col1, "YYYYMMDD")) %>%
  show_query()

#><SQL>
#>SELECT "row.names", "Col1", "Col2", TO_DATE("Col1", 'YYYYMMDD') AS "date"
#>FROM "tmp"

tbl(con, "tmp") %>% 
  mutate(date = to_date(Col1, "YYYYMMDD")) %>% #this works on DBMS
  collect() %>% #This retrive to R session
  str()

#>Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 2 obs. of  3 variables:
#> $ row.names: chr  "1" "2"
#> $ Col1     : chr  "20180212" "20180213"
#> $ Col2     : chr  "A" "B"
#> $ date     : Date, format: "2018-02-12" "2018-02-13"

使用dbGetQuery()函数

dbGetQuery(con, "SELECT * FROM tmp") %>% 
  str()

#>'data.frame': 2 obs. of  3 variables:
#> $ row.names: chr  "1" "2"
#> $ Col1     : chr  "20180212" "20180213"
#> $ Col2     : chr  "A" "B"

dbGetQuery(con, "SELECT * FROM tmp") %>%
  mutate(date = as.Date(Col1, format = "%Y%m%d")) %>% #This works on R session
  str()

#>'data.frame': 2 obs. of  4 variables:
#> $ row.names: chr  "1" "2"
#> $ Col1     : chr  "20180212" "20180213"
#> $ Col2     : chr  "A" "B"
#> $ date     : Date, format: "2018-02-12" "2018-02-13"

结论

tbl() 函数是 R 编程中 dbGetQuery() 的高级函数。考虑重新设计您的代码链,了解这两个函数之间的差异以及它们的最佳用途。

关于r - 是否可以直接在类 tbl_sql(或 tbl_dbi)上运行 SQL 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48729832/

相关文章:

在R中用空格替换tibble中的单词而不使用反连接

r - 如何在facet_wrap中添加表达式到标签?

r - 仅允许 OCR 中的某些单词

r - 我正在尝试按特定条件将 2 行数据合并或聚合为 1 行

r - 在创建列表 tibble 列时在 "mutation"中使用 dplyr::sym() 会导致错误 is_symbol(x): object '.x' not found

r - 将 tibble 中的每一行转换为列标题

r - ggplot2使图例键填充透明

删除括号、括号和/或大括号内的文本

r - 过滤后使用左连接更新数据

r - 有没有办法合并 dplyr::filter_at 结果? (一次过滤多个变量)