使用 R 的
DBI
,我需要:
rbind
ed按照R术语或union
ed按照SQL术语);dbBind
/dbGetquery
满足要求 1 和 2,但我需要使用 dbWriteTable
将生成的数据框写入数据库,这是低效的:
library(DBI)
con <- dbConnect(RSQLite::SQLite(), ":memory:")
dbWriteTable(con, "iris", iris)
res <- dbGetQuery(con,
"select * from iris where Species = ?",
params = list(c("setosa", "versicolor")))
dbWriteTable(con, "mytable", res)
相反,
dbExecute
满足需求3,但我认为它没有“rbind
特征”。当然,这会引发错误,因为表格会被覆盖:
dbExecute(con,
"create table mytable as select * from iris where Species = ?",
params = list(c("setosa", "versicolor")))
最有效/推荐的方法是什么?
备注:
1) 使用第一个参数创建表,然后将其他每个参数插入其中。
library(RSQLite)
con <- dbConnect(SQLite())
dbWriteTable(con, "iris", iris)
parms <- c("setosa", "versicolor")
dbExecute(con, "create table mytable as
select * from iris where Species = ?",
params = parms[1])
for (p in parms[-1]) {
dbExecute(con, "insert into mytable
select * from iris where Species = ?",
params = p)
}
# check
res <- dbGetQuery(con, "select * from mytable")
str(res)
2) 交替生成 SQL 语句的文本来完成这一切。 sqldf 引入 RSQLite 和 gsubfn,后者提供启用文本替换的 fn$。
library(sqldf)
con <- dbConnect(SQLite())
dbWriteTable(con, "iris", iris)
parms <- c("setosa", "versicolor")
parmString <- toString(sprintf("'%s'", parms))
fn$dbExecute(con, "create table mytable as
select * from iris where Species in ($parmString)")
# check
res <- dbGetQuery(con, "select * from mytable")
str(res)
3) (2)的变体是插入适当数量的问号。
library(sqldf)
con <- dbConnect(SQLite())
dbWriteTable(con, "iris", iris)
params <- list("setosa", "versicolor")
quesString <- toString(rep("?", length(params)))
fn$dbExecute(con, "create table mytable as
select * from iris where Species in ($quesString)", params = params)
# check
res <- dbGetQuery(con, "select * from mytable")
str(res)
基于@r2evans 的评论和@G.Grothendieck 的回答,我使用了直接插入表中的参数化查询,而不是查询/下载/组合/上传。
首先,我创建了包含适当列的表来收集结果:
library(DBI)
con <- dbConnect(RSQLite::SQLite(), ":memory:")
create_table <-
"
CREATE TABLE
warpbreaks2 (
breaks real,
wool text,
tension text
);
"
dbExecute(con, create_table)
然后我执行了一个
INSERT INTO
步骤:
dbWriteTable(con, "warpbreaks", warpbreaks)
insert_into <-
"
INSERT INTO
warpbreaks2
SELECT
warpbreaks.breaks,
warpbreaks.wool,
warpbreaks.tension
FROM
warpbreaks
WHERE
tension = ?;
"
dbExecute(con, insert_into, params = list(c("L", "M")))
这是一个用于说明目的的虚拟示例。它可以通过例如更直接地实现:
direct_query <-
"
CREATE TABLE
warpbreaks3 AS
SELECT
*
FROM
warpbreaks
WHERE
tension IN ('L', 'M');
"
dbExecute(con, direct_query )