是否有 'cleaner' 连接查询字符串的方法?

Is there a 'cleaner' way to concatenate a query string?

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

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)
    }

当我调用这个函数并尝试用它查询我们的数据库时,我得到:

An error has been thrown from the AWS Athena client. Athena Error No: 372, HTTP Response Code: 1, Error Message: SYNTAX_ERROR: line 3:15: '=' cannot be applied to varchar, integer

有 'right' 方法吗?我如何构造一个带有变量的查询字符串然后传递给 DBI::dbGetQuery()

这里有两个选项,我们可以在其中引用 (') 输入作为字符串作为 monthyear 函数 return 数值

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)
        }

我们可以使用 gsubfn 中的 fn$ 来执行字符串插值。我们将使用 NULL 而不是实际连接,并使用 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")

也可以分两步完成:

query <- fn$c("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")
dbGetQuery(con, query)