我对SQL非常陌生,所以我很抱歉,如果这是一个简单的问题,我在搜索时没有找到任何东西,但我可能错过了明显的搜索条件。
我正在尝试下载一组市政债券的所有交易数据,其中我有一个CUSIP列表,当前存储为一个.txt文件,每行有一个CUSIP。WRDS的在线版本允许用户上传这样的.txt文件来检索他们的数据。
我想在R中自动化这个过程,并按照WRDS指南在R中设置SQL查询,最后我将使用以下内容
res <- dbSendQuery(wrds, "select *
from msrb.msrb
where cusip IN ???")
data <- dbFetch(res, n=-1)
dbClearResult(res)
data我如何将我的CUSIP列表实际输入查询?直接列出每个CUSIP太长了。我可以以某种方式引用.txt文件,或者至少在R中引用字符向量吗?有没有更好的方法?
发布于 2020-10-05 14:50:22
我认为有两种有效的方法可以编程地在SQL中执行IN (...),还有一种方法很流行,但风险很大(我通常不赞成)。
使用参数绑定的
DBI允许绑定多少参数可能有一个真正的限制,但我不知道;我不知道IN (...)实现是否经常限制您可以放在文字IN (...)语句中的值的数量(我刚刚用5000测试了PG11,没有问题)。在某种程度上,使用下面的备选案文2可能更有效或更可取。然而,如果我们说的是这么多,那就试试这个。cusip <- c(.)#向量cusips params <-粘贴(paste0(“$ ",seq_along(Cusip)),cusip=”,") ret <- DBI:dbGetQuery(con,粘贴(“select* from msrb.msrb msrb.msrb cusip in (",params,")"),params =as.list(Cusip))
($1, $2, $3)的使用是针对postgres的;其他DBMSes可能使用不同的名称,包括(?,?,?) (sql server和其他)。
CUSIPs <- c(.)#向量cusips tmptbl <- paste0("tmptable_",con(sample(9),con=“”)DBI:dbWriteTable(con,tmptbl,data.frame(cusip = cusip )) DBI::dbGetQuery(con,粘贴(“从msrb.msrb中选择* cusip in",”,“(从”,tmptbl,“)选择cusip)
或连接到temp表,使用
DBI::dbGetQuery(con,粘贴(“选择msrb.* from ",tmptbl,"t",”左加入t.cusip =t.cusip])
总的来说,
IN (...)。您可以使用glue::glue_sql确保始终使用正确的引号(针对特定DBMS);如果没有,使用单引号通常是安全的。cusip <- c(.)#向量cusip参数<- glue::glue_sql(“( "),粘贴(Cusip),折叠= ",”)#或params <- glue::glue_sql(“({cusip*})”,.con = con) DBI::dbGetQuery
注意,glue::glue_sql提供了*表示法。来自?glue::glue_sql:
如果在胶表达式的末尾放置“*”,则值将用逗号折叠。例如,这对于SQL运算符很有用.
对于所有三种方法,我都使用了更直接的DBI::dbGetQuery,但如果您愿意,仍然可以使用DBI::dbSendQuery/DBI::dbFetch两步。
根据msrb表及其索引的大小,这些查询可能不会影响所有优化。如果是这样的话,请考虑根据来自DBA的建议添加到查询中。
https://stackoverflow.com/questions/64199024
复制相似问题