首页 > 解决方案 > 如何使用 R 批量获取数据

问题描述

我在 R 中有一个具有以下结构的数据框:

ID      Date
ID-1    2020-02-10 13:12:04
ID-2    2020-02-12 15:02:24
ID-3    2020-02-14 12:25:32

我正在使用以下查询从 MySQL 中获取数据,因为我有大量 if ID(即 ~90K),所以我遇到了问题。当我通过 500-1000ID它工作正常但通过 90K Id 它会引发错误。

Data_frame<-paste0("
SELECT  c.ID, e.name,d.output
FROM Table1 c
left outer join Table2 d ON d.ID=c.ID
LEFT outer JOIN Table1 e ON e.ID_2=d.ID_2
WHERE e.name in ('Name1','Name2') 
AND c.ID IN (", paste(shQuote(DF$ID, type = "sh"),collapse = ', '), ")
                      ;")

查询以我需要使用的以下方式rbind返回DF输出ID

查询输出<-

ID       Name     output
ID-1     Name1    23
ID-1     Name2    20
ID-2     Name1    40
ID-2     Name2    97
ID-3     Name1    34
ID-3     Name2    53

所需输出:

ID      Date                   Name1      Name2
ID-1    2020-02-10 13:12:04    23         20
ID-2    2020-02-12 15:02:24    40         97
ID-3    2020-02-14 12:25:32    34         53

我已经尝试了下面提到的代码:

createIDBatchVector <- function(x, batchSize){
   paste0(
     "'"
     , sapply(
       split(x, ceiling(seq_along(x) / batchSize))
       , paste
       , collapse = "','"
     )
     , "'"
   )
 }
 
# second helper function
 createQueries <- function(IDbatches){
 paste0("
    SELECT  c.ID, e.name,d.output
    FROM Table1 c
    left outer join Table2 d ON d.ID=c.ID
    LEFT outer JOIN Table1 e ON e.ID_2=d.ID_2
    WHERE e.name in ('Name1','Name2') 
    AND c.ID IN (", paste(shQuote(DF$ID, type = "sh"),collapse = ', '), ")
                          ;")}
 
# ------------------------------------------------------------------
 
# and now the actual script
 
# first we create a vector that contains one batch per element
IDbatches <- createIDBatchVector(DF$ID, 2)
 
# It looks like this:
# [1] "'ID-1','ID-2'" "'ID-3','ID-4'" "'ID-5'" 
 
# now we create a vector of SQL-queries out of that
# queries <- createQueries(IDbatches)
 
df_final <- data.frame() # initialize a dataframe
 
conn <- database # open a connection
for (query in queries){ # iterate over the queries
    df_final <- rbind(df_final, dbGetQuery(conn,query))}

标签: rdataframedplyrtidyverse

解决方案


令人惊讶的 90k 行会杀死您的 SQL,但这就是生活

不确定我理解为什么你正在做你正在做的事情而不是循环一个 for

for (batches in 0:90) {
b = batches*1000
 SELECT ...
 ... WHERE ID > b & < b+1000

rbind(myData, result)
}

(这不是解决方案只是方法)

但是,如果您的方法有效,那么您想要的就是 dplyr::pivot_wider()


推荐阅读