R 是否可以直接在类tbl_SQL(或tbl_dbi)上运行SQL查询?

R 是否可以直接在类tbl_SQL(或tbl_dbi)上运行SQL查询?,r,dplyr,tibble,rsqlite,dbplyr,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,

示例代码:

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")
显然,我可以在con上使用dbGetQuery,但我想知道是否有一种方法可以让它直接在d0上工作


谢谢。

不,您不能以这种方式将
dbGetQuery
dplyr
一起使用,它只能与
DBIConnection
一起使用

另外,第一个查询是冗余的,
d0
已经表示了
USArrests
数据,第二个查询是无意义的

dplyr
使用了稍微不同的方法,它使用
dplyr
动词并创建SQL查询:

d0 %>% filter(Murder > 10) %>% show_query()

好的,查看
str
有助于揭示如何使用以下命令访问所需的元素:

  con <- d0$src$con
  db_name <- db_list_tables(con)[1]

con一方面,是
tbl()
函数,它是一个SQL语句,类型为
SELECT*FROM Table
,它在DBMS上工作,要从数据库服务器检索数据,它需要一个pull函数,如
collect()
。另一方面,是函数
dbGetQuery()
,它使用SQL查询将数据检索到R会话中。两者都需要一个到服务器的连接和一个语句,但第一个是使用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")
使用
dbGetQuery()
函数

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(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-programming中高于
dbGetQuery()
的高级函数。考虑重新设计您的代码链,了解它们的功能和最佳用途之间的差异。

Hy@ M0NHAKK。我知道它不起作用,问题是我怎样才能写出像“过滤器”这样的东西。它显然运行了一些SQL,我希望能够编写一个自定义函数来完成它。@TalGalili我不明白你想要什么。您想编写自己的
过滤器
?然后您可以查看
dplyr
开发指南。不是
tbl_sql
tbl_dbi
,而是sqldf包可以使用sql和各种后端(包括sqlite)处理数据帧<代码>库(sqldf);sqldf(“select*from USArrests limit 3”)
这看起来很有趣。你能解释一下它在做什么吗?嗨,Rasmus,它从dbplyr对象(tbl_lazy,tbl_sql)获取原始连接和使用的数据库名。通过这种方式,我们可以直接在其上使用dbGetQuery之类的东西,而无需首先使用dplyr collect函数。我个人想要它来获取行的样本——但只有在对象上没有使用其他dplyr动词时,它才有意义。
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(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"