我试图仅从名称中已经存在的数据框中存在的数据库中提取数据。我不确定如何将列表包括在我的选择陈述中。
奖金:我需要将所有数据重新格式化为更友好的格式。
library(RMySQL)
library(DBI)
db_con <- dbconnect(RMySQL::MySQL(),
username: "user",
password: "1234",
dbname = "test")
df <- as.data.frame(tbl(db_con, sql("SELECT name, loc, type, value FROM data"))
这将读取整个数据表。我需要根据名称字段限制输入的内容。
df$names <- "cat, hamster"
name_filter <- df$names
当前df:
# name loc type val
1 cat ab12 a 1
2 cat 1233 a 0
3 dog ab12 a 0
4 dog 45ff b 1
5 hamster ab12 a 1
6 hamster 45ff b 0
所需的输出,而无需在以下位置读取整个表:SELECT * WHERE name IN name_filter?
# loc type cat hamster
1 ab12 a 1 1
2 1233 a 0 0
3 45ff b 0 0
编辑:尝试在数据上使用库(重塑)效果不是很好。不过我可能做错了...我目前正在提取一个约有4500万行的截断的数据库。 (整个数据库约为3亿。)
cast(df, loc+type ~ name, value = "val")
这将导致很长的暂停,然后出现“聚合需要fun.aggregate:长度用作默认值”错误,然后出现似乎是无休止的暂停。
EDIT2:名称列表长数百个,并且每次请求时都不同。每个名称有成千上万个值。
EDIT3:我在另一个线程中发现了这一点,该线程试图基于值列表生成select语句。我不确定它是否有用,因为我也无法使其正常工作。
list <- list$Name
sel <- "SELECT name, loc, type, val FROM data WHERE name IN (%s)"
sql1 <- sprintf(sel,paste(list, collapse =","))
yields:
"SELECT name, loc, type, val FROM data WHERE name IN (dog,cat,hamster,square,triangle,circle,ball,horse,lion)
EDIT4:尝试使用以下内容,但遇到有关MariaDB语法的错误。 MySQL和MariaDB之间的select语句有区别吗?
list <- df$Name
sqlqry <- "SELECT data.loc, data.type"
for (i in 1:length(list)) {
sqlqry <- paste0(sqlqry, sprintf(", MAX(CASE WHEN data.name = '%s'
THEN 1 ELSE 0 END) AS %s",list[i], list[i]))
}
sqlqry <- paste0(sqlqry, "FROM
data
GROUP BY
data.loc
, data.type")
test <- dbSendQuery(db_con, sqlqry)
答案 0 :(得分:0)
此查询将为您提供所需的结果。
SELECT
data.loc
, data.type
, MAX(CASE WHEN data.name = 'cat' THEN 1 ELSE 0 END) AS cat
, MAX(CASE WHEN data.name = 'hamster' THEN 1 ELSE 0 END) AS hamster
FROM
data
GROUP BY
data.loc
, data.type
为避免扫描整个表,您将需要(覆盖)索引。
该索引应使上述查询的选择速度更快。
ALTER TABLE data ADD INDEX <index_name> (loc, type, name)
, ALGORITHM=INPLACE
, LOCK=NONE
, ALGORITHM=INPLACE, LOCK=NONE
仅适用于InnoDB引擎。它是InnoDB's online DLL的一部分,它不能使表停机。