有没有一种“更清洁”的方式来连接查询字符串?

时间:2020-01-25 00:21:10

标签: r dbi rodbc dbplyr

我正在将查询字符串传递给连接,结果应如下所示:

select game_name, month, count(*) as count
  from device_metrics.mtu_events
 where YEAR = '2019' and month between '07' and '09'
 group by game_name, month
 order by game_name asc, month asc

如果我将上面的代码块作为单个字符串传递到DBI::dbGetQuery(con, myquery)

,此方法就很好

但是日期是闪亮的应用程序中的变量,因此我尝试创建一个函数来生成查询字符串:

my_query <- function(start_date, end_date) {
        yr <- year(ymd(start_date))
        month_start <- month(ymd(start_date))
        month_end <- month(ymd(end_date))

        query <- paste0(
            "select game_name, month, count(*) as count
   from device_metrics.mtu_events
   where YEAR = ", yr, " and month between ", month_start, " and ", month_end, 
            " group by game_name, month
 order by game_name asc, month asc")

        return(query)
    }

当我调用此函数并尝试使用它查询数据库时,我得到:

AWS Athena客户端引发了一个错误。雅典娜错误编号:372,HTTP响应代码:1,错误消息:SYNTAX_ERROR:第3:15行:“ =”无法应用于varchar,整数

是否有“正确”的方法来做到这一点?如何构造带有变量的查询字符串,然后传递给DBI::dbGetQuery()

2 个答案:

答案 0 :(得分:3)

这里有两个选项,我们可以将输入{'引为字符串,例如monthyear函数返回数字值

my_query <- function(start_date, end_date) {
        yr <- year(ymd(start_date))
        month_start <- month(ymd(start_date))
        month_end <- month(ymd(end_date))

        query <- paste0(
            "select game_name, month, count(*) as count
   from device_metrics.mtu_events
   where YEAR = '", yr, "' and month between '", month_start, "' and '", month_end, 
            "' group by game_name, month
 order by game_name asc, month asc")

        return(query)
    }

使用sprintf

my_query <- function(start_date, end_date) {
            yr <- year(ymd(start_date))
            month_start <- month(ymd(start_date))
            month_end <- month(ymd(end_date))

            query <- sprintf("select game_name, month, count(*) as count
       from device_metrics.mtu_events
       where YEAR = '%d'  and month between '%02d' and '%02d' group by game_name, month
     order by game_name asc, month asc", yr, month_start, month_end)

            return(query)
        }

答案 1 :(得分:2)

我们可以使用gsubfn中的activity_main进行字符串插值。为了重现性,我们将使用NULL代替实际的连接,并使用fn$代替fn$list,但是您可以同时替换两者。执行此操作时,请勿在名称中使用下划线或点。

fn$dbGetQuery

它可以分两个步骤完成:

library(gsubfn)

yr <- 2019
monthStart <- '07'
monthEnd <- '09'
con <- NULL

fn$list(con, "select game_name, month, count(*) as count
  from device_metrics.mtu_events
 where YEAR = '$yr' and month between '$monthStart' and '$monthEnd'
 group by game_name, month
 order by game_name asc, month asc")
相关问题