0

我想做一些与这些非常相似的事情:

当mysql WHERE 子句为空时,返回所有行

可以让 PHP MYSQL 查询忽略 WHERE 子句中的空变量吗?

如果我作为子集的变量是,我希望忽略 where 子句NULL。但是,我正在使用 dbGetQuery 从 R 访问我的 MySQL 数据库。到目前为止,我有这样的代码

write_pid_clause = function(p_id=NULL){
 if(is.null(p_id)){return(NULL)}
 else {return(paste0("where project_id = ",p_id)  )}
}

如果未指定,它会编写正确的where语句行为,以及代码:p_id

  dbGetQuery( con,paste0("select MIN(completion_date) from run ",write_pid_clause(p_id))))

这可以正常工作,但是,如果我想在 where 子句中插入更多条件,例如如果我想添加条件and status = 'complete'when ,我会遇到困难p_id = NULL

有没有人对我如何在 R 中优雅地做到这一点有什么好主意?

编辑 这里有更多代码来演示我正在尝试做的事情,这是关于连接and后的子句(这样做where有点棘手)

make_and_clauses = function(p_id = "",start_date="", end_date=""){

 conditions = list(
   list(" and r.project_id ='", p_id,"'"),
   list(" and r.completion_date >= '",start_date,"'"),
   list(" and r.completion_date <= '", end_date, "'"))
 condition_values = c(p_id,start_date, end_date)
 conditions[which(condition_values =="")] <- ""
 conditions = unlist(conditions,recursive=TRUE)
 paste0(conditions,collapse="")

}

给出输出

> make_and_clauses(2,3,4)
[1] " and r.project_id ='2' and r.completion_date >= '3' and r.completion_date <= '4'"
> make_and_clauses(2,,4)
[1] " and r.project_id ='2' and r.completion_date <= '4'"
> make_and_clauses(,3,2)
[1] " and r.completion_date >= '3' and r.completion_date <= '2'"

>
4

2 回答 2

1

我认为没有一种简单/简单/清晰的方法可以实现您想要的。如果您希望能够添加多个子句,每个子句都依赖于变量的内容,则必须构建每个子句。我能想到的唯一相关的 SQL 技巧是放入WHERE 1=1SQL 语句,然后AND column = value为每个值添加。这样,如果您遗漏一个,语法仍然是正确的。

我看到@Marek 提供了带有代码的答案;也许你可以结合这些答案来产生一个可行的解决方案。

于 2014-05-13T06:05:02.470 回答
1

从您的功能开始,我提出了类似的建议:

make_and_clauses <- function(p_id, start_date, end_date) {
    conditions = c(
        if (!missing(p_id)) sprintf("r.project_id ='%i'", p_id),
        if (!missing(start_date)) sprintf("r.completion_date >= '%i'", start_date),
        if (!missing(end_date)) sprintf("r.completion_date <= '%i'", end_date)
    )
    paste(conditions, collapse=" and ")
}

返回:

make_and_clauses(2,3,4)
# [1] "r.project_id ='2' and r.completion_date >= '3' and r.completion_date <= '4'"
make_and_clauses(2,,4)
# [1] "r.project_id ='2' and r.completion_date <= '4'"
make_and_clauses(,3,2)
# [1] "r.completion_date >= '3' and r.completion_date <= '2'"
make_and_clauses(,3,)
# [1] "r.completion_date >= '3'"

根本没有争论会导致什么重要:

make_and_clauses(,,)
# [1] ""

所以可以写WHERE子句:

make_and_clauses <- function(p_id, start_date, end_date) {
    conditions = c(
        if (!missing(p_id)) sprintf("r.project_id ='%i'", p_id),
        if (!missing(start_date)) sprintf("r.completion_date >= '%i'", start_date),
        if (!missing(end_date)) sprintf("r.completion_date <= '%i'", end_date)
    )
    if (length(conditions)>0) paste("WHERE", paste(conditions, collapse=" and ")) else ""
}

并将其用作

paste("select MIN(completion_date) from run", make_and_clauses(,3,2))
# [1] "select MIN(completion_date) from run WHERE r.completion_date >= '3' and r.completion_date <= '2'"
paste("select MIN(completion_date) from run", make_and_clauses())
# [1] "select MIN(completion_date) from run "
于 2014-05-13T20:12:51.730 回答