在 R 中使用 RODBC 创建循环 SQL QUERY
creating a looped SQL QUERY using RODBC in R
首先,感谢您花时间查看我的问题,无论您是否回答!
我正在尝试创建一个循环遍历我的 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)
}
但是,这不会查询任何内容。我相信这与我指定迭代的开始和结束日期的方式有关。
如果有人可以提供帮助,我们将不胜感激。如果您需要进一步的解释,请随时询问!
当前设置出现了一些语法问题:
LOOP:您不会遍历数据框的所有行,而只会遍历单列中的原子 ID 值,df$ID
。在同一循环中,您将 df$Start_Date
和 df$End_Date
的 整个 向量传递到查询串联中。
日期:您的日期格式与 'YYYY-MM-DD' 的大多数数据库日期格式不一致。还有一些像 Oracle,你需要字符串到数据的转换:TO_DATE(mydate, 'YYYY-MM-DD')
.
上述几个性能/最佳实践问题:
参数化:虽然出于安全原因不需要参数化,因为您的值不是由可以注入恶意 SQL 代码的用户输入生成的,但为了可维护性和可读性,建议使用参数化查询。因此,考虑这样做。
GROWING OBJECTS:根据 Patrick Burn 的 Inferno Circle 2:Growing Objects,R 程序员应该避免增长多维对象,例如数据框在可能导致内存中过度复制的循环内。相反,在循环外构建数据帧列表 rbind
一次。
话虽如此,您可以通过将数据框保存为数据库 table 然后连接到最终 table 以进行过滤、连接查询导入来避免任何循环或列表需求。这假定您的数据库用户具有 CREATE TABLE
和 DROP 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)
首先,感谢您花时间查看我的问题,无论您是否回答!
我正在尝试创建一个循环遍历我的 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)
}
但是,这不会查询任何内容。我相信这与我指定迭代的开始和结束日期的方式有关。
如果有人可以提供帮助,我们将不胜感激。如果您需要进一步的解释,请随时询问!
当前设置出现了一些语法问题:
LOOP:您不会遍历数据框的所有行,而只会遍历单列中的原子 ID 值,
df$ID
。在同一循环中,您将df$Start_Date
和df$End_Date
的 整个 向量传递到查询串联中。日期:您的日期格式与 'YYYY-MM-DD' 的大多数数据库日期格式不一致。还有一些像 Oracle,你需要字符串到数据的转换:
TO_DATE(mydate, 'YYYY-MM-DD')
.
上述几个性能/最佳实践问题:
参数化:虽然出于安全原因不需要参数化,因为您的值不是由可以注入恶意 SQL 代码的用户输入生成的,但为了可维护性和可读性,建议使用参数化查询。因此,考虑这样做。
GROWING OBJECTS:根据 Patrick Burn 的 Inferno Circle 2:Growing Objects,R 程序员应该避免增长多维对象,例如数据框在可能导致内存中过度复制的循环内。相反,在循环外构建数据帧列表
rbind
一次。
话虽如此,您可以通过将数据框保存为数据库 table 然后连接到最终 table 以进行过滤、连接查询导入来避免任何循环或列表需求。这假定您的数据库用户具有 CREATE TABLE
和 DROP 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)