Есть ли «более чистый» способ объединения строки запроса? - PullRequest
1 голос
/ 25 января 2020

Я передаю строку запроса соединению, и результат должен выглядеть следующим образом:

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

Когда я вызываю эту функцию и пытаюсь запросить ее в нашей базе данных, я получаю :

Ошибка клиента Athena AWS. Ошибка Афины: 372, код ответа HTTP: 1, сообщение об ошибке: SYNTAX_ERROR: строка 3:15: «=» нельзя применить к varchar, целое число

Существует ли «правильный» способ сделать это? Как я могу построить строку запроса с переменными и затем перейти к DBI::dbGetQuery()

Ответы [ 2 ]

3 голосов
/ 25 января 2020

Вот два варианта, в которых мы можем заключить (') входные данные в виде строки как month, year функции возвращают цифры c значения

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)
        }
2 голосов
/ 25 января 2020

Мы можем использовать fn$ из gsubfn для выполнения строковой интерполяции. Мы будем использовать 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)
...