在R中使用RODBC创建循环SQL查询
首先也是最重要的一点——感谢您抽出时间来查看我的问题,无论您是否回答 我试图创建一个函数,使用R中的RODBC包循环通过我的df并查询来自SQL的必要数据。但是,我在设置查询时遇到了问题,因为查询的参数在每次迭代中都会发生变化(下面的示例) 因此,我的df如下所示:在R中使用RODBC创建循环SQL查询,r,rodbc,R,Rodbc,首先也是最重要的一点——感谢您抽出时间来查看我的问题,无论您是否回答 我试图创建一个函数,使用R中的RODBC包循环通过我的df并查询来自SQL的必要数据。但是,我在设置查询时遇到了问题,因为查询的参数在每次迭代中都会发生变化(下面的示例) 因此,我的df如下所示: ID Start_Date End_Date 1 2/2/2008 2/9/2008 2 1/1/2006 1/1/2007
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)
}
data\u pull当前设置中出现了几个语法问题:
循环:不遍历数据帧的所有行,只遍历单个列中的原子ID值,df$ID
。在同一循环中,您将df$Start\u Date
和df$End\u Date
的整个向量传递到查询连接中
日期:您的日期格式与大多数“YYYY-MM-DD”数据库日期格式不一致。还有一些像Oracle这样的应用程序需要字符串到数据的转换:到_DATE(mydate,'YYYY-MM-DD')
前面提到的几个性能/最佳实践问题:
参数化:虽然出于安全原因不需要参数化,因为您的值不是由可能注入恶意SQL代码的用户输入生成的,但为了可维护性和可读性,建议使用参数化查询。因此,考虑这样做。
不断增长的对象:根据Patrick Burn的圆圈2:不断增长的对象,R程序员应该避免在循环中增长多维对象,如数据帧,这可能会导致内存中的过度复制。相反,在循环外部构建一个数据帧列表,以rbind
一次
也就是说,通过将数据帧保存为数据库表,然后连接到最终表以进行过滤、连接查询导入,可以避免任何循环或列表需求。这假定数据库用户具有创建表
和删除表
权限
# 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)
#将日期字段转换为日期类型
df从不对SQL查询使用paste
连接,最好的情况是语法错误,最坏的情况是(无论有意与否)。相反,使用rodbext
(相关问题:)(除非RODBC
已经开始直接使用它,否则我真的很惊讶他们还没有实现它,因为它是良好数据库实践的基础)。谢谢@r2evans,我将学习并尝试实现这一点。其次,不要像那样重复使用rbind
,从长远来看,这会破坏性能(每次调用rbind
都会完整复制前面和正在添加的所有数据)。由于rodbext::sqlExecute
直接支持使用帧进行矢量化(请参见第2.3.2节),因此根本不需要循环。是的,rbind
在循环内运行会导致二次复制。始终避免在回路中生长物体谢谢你们@Parfait我会尝试重新编写这篇文章非常感谢你们花时间来完成这篇文章。我真的很感激,没问题。新年快乐,编码快乐!