从列表名称及其值生成SQL查询

时间:2015-10-28 18:05:03

标签: r list rodbc

基本上我试图通过unlistingpaste派生SELECT语句的WHERE部分 - 列表名称代表数据库的列表TABLE列和相应的列表值等于WHERE子句。这是一个简化的例子......

lst <- list(DATE=as.Date('2015-10-25'), NUM="0001", PROD="SOMETHING")
lst
    $DATE
[1] "2015-10-25"

$NUM
[1] "0001"

$PROD
[1] "SOMETHING"

理想情况下,这将被转换为(WHERE之后的第二行开始的有趣位:)

"SELECT SOME_COLUMNS WHERE  
DATE = '", lst$DATE, "' AND 
NUM = '", lst$NUM, "' AND 
PROD = '" lst$PROD ,"'")

我很确定有人知道apply()

的一些奇特组合

paste(..,collapse ="' AND ")和/或substitute()能够以优雅的形式实现这一目标,但我被困住了。

3 个答案:

答案 0 :(得分:5)

我不知道这是否优雅但它应该有效:

sql <- paste0("SELECT ", 
              paste0(names(lst),collapse=','), 
              " WHERE\n",
              paste(lapply(names(lst),function(x)paste0(x," = '",lst[[x]],"'")),collapse="AND\n"))

> cat(sql)
SELECT DATE,NUM,PROD WHERE
DATE = '2015-10-25'AND
NUM = '0001'AND
PROD = 'SOMETHING'

答案 1 :(得分:3)

你在找这样的东西吗?

lst2sql <- function(lst) {
    sql <- "SELECT col1, col2 FROM table1 WHERE"

    predicates <- vapply(names(lst), function(n) { paste(n, " = '", lst[[n]], "'", sep="") }, character(length(names)))

    paste(sql, paste(predicates, collapse=" AND "))
}

在您的示例列表中调用时,将生成:

"SELECT col1, col2 FROM table1 WHERE DATE = '2015-10-25' AND NUM = '0001' AND PROD = 'SOMETHING'"

答案 2 :(得分:3)

sprintf通常很有用:

lst <- list(DATE=as.Date('2015-10-25'), NUM="0001", PROD="SOMETHING") 
q <- "SELECT SOME_COLUMNS WHERE DATE = '%s' AND NUM = '%s' AND PROD = '%s'"

> sprintf(q,lst[[1]],lst[[2]],lst[[3]])
[1] "SELECT SOME_COLUMNS WHERE DATE = '2015-10-25' AND NUM = '0001' AND PROD = 'SOMETHING'"

另外,请参阅我的其他答案here以获取更多想法。如果你做了很多,那么为它构建一些专门的工具是值得的,正如我在答案中概述的那样。