在R中使用RODBC创建循环的SQL查询

永巴德院

首先-谢谢您抽出宝贵的时间来查看我的问题,无论您是否回答!

我正在尝试创建一个函数,该函数遍历我的df并使用R中的RODBC包从SQL查询必要的数据。但是,我在设置查询时遇到了麻烦,因为查询的参数在每次迭代中都会发生变化(示例下面)

所以我的df看起来像这样:

     ID     Start_Date    End_Date    
     1       2/2/2008      2/9/2008
     2       1/1/2006      1/1/2007
     1       5/7/2010      5/15/2010
     5       9/9/2009      10/1/2009

如何在sql程序中指定开始日期和结束日期?

这是我到目前为止的内容:

 data_pull <- function(df) {
    a <- data.frame()
    b <- data.frame()

    for (i in df$id)
{ 
    dbconnection <- odbcDriverConnect(".....")

    query <- paste("Select ID, Date, Account_Balance from Table where ID = (",i,") and Date > (",df$Start_Date,") and Date <= (",df$End_Date,")")

    a <- sqlQuery(dbconnection, paste(query))
    b <- rbind(b,a)
 }
  return(b)
 }

但是,这不会查询任何内容。我认为这与我指定迭代的开始日期和结束日期有关。

如果有人可以提供帮助,将不胜感激。如果您需要进一步的解释,请随时询问!

完善

当前设置会引起一些语法问题:

  1. 循环:您无需遍历数据帧的所有行,而仅遍历单列中的原子ID值df$ID在同一循环您传递的整个的载体df$Start_Datedf$End_Date成查询级联。

  2. 日期:日期格式与大多数数据库日期格式“ YYYY-MM-DD”不一致。还有一些其他的东西,例如Oracle,您需要将字符串转换为数据:TO_DATE(mydate, 'YYYY-MM-DD')

上面提到的几个性能/最佳实践问题:

  1. 参数化:出于安全原因不需要参数化,因为您的值不是由可以注入恶意SQL代码的用户输入生成的,出于可维护性和可读性考虑,建议您进行参数化查询。因此,请考虑这样做。

  2. 增长的对象:根据Patrick Burn的Inferno Circle 2:增长的对象,R程序员应避免在循环内增长多维对象(例如数据帧),这会导致内存中的过度复制。相反,构建rbind 一次循环之外的数据帧列表


话虽如此,您可以通过将数据帧另存为数据库表,然后将其联接到最终表以进行过滤的联接查询导入,从而避免任何循环或列表需求。这假定您的数据库用户具有CREATE TABLEDROP TABLE特权。

# CONVERT DATE FIELDS TO DATE TYPE
df <- within(df, {
          Start_Date = as.Date(Start_Date, format="%m/%d/%Y")
          End_Date = as.Date(End_Date, format="%m/%d/%Y")
})

# SAVE DATA FRAME TO DATABASE
sqlSave(dbconnection, df, "myRData", rownames = FALSE, append = FALSE)

# IMPORT JOINED AND DATE FILTERED QUERY
q <- "SELECT ID, Date, Account_Balance 
      FROM Table t
      INNER JOIN myRData r 
        ON r.ID = t.ID 
        AND t.Date BETWEEN r.Start_Date AND r.End_Date"

final_df <- sqlQuery(dbconnection, q)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章