Добавьте динамическое значение в RMySQL getQuery

Можно ли передать значение в запрос в dbGetQuery из пакета RMySQL.

Например, если у меня есть набор значений в символьном векторе:

df <- c('a','b','c')

И я хочу пройтись по значениям, чтобы извлечь для каждого конкретное значение из базы данных.

library(RMySQL)    
res <- dbGetQuery(con, "SELECT max(ID) FROM table WHERE columna='df[2]'")

Когда я пытаюсь добавить ссылку на значение, я получаю сообщение об ошибке. Интересно, можно ли добавить значение из объекта R в запрос.

2 ответа

Решение

Одним из вариантов является манипулирование строкой SQL внутри цикла. На данный момент у вас есть строковый литерал, 'df[2]' R не интерпретируется как что-либо кроме символов. В моем ответе будут некоторые неясности, потому что df в вашем Q явно не фрейм данных (это символьный вектор!). Нечто подобное будет делать то, что вы хотите.

Сохраните вывод в числовом векторе:

require(RMySQL)
df <- c('a','b','c')
out <- numeric(length(df))
names(out) <- df

Теперь мы можем зациклить элементы df выполнить ваш запрос три раза. Мы можем настроить цикл двумя способами: i как число, которое мы используем для ссылки на элементы df а также outили ii) с i как каждый элемент df в свою очередь (т.е. a, затем b...) Я покажу обе версии ниже.

## Version i
for(i in seq_along(df)) {
    SQL <- paste("SELECT max(ID) FROM table WHERE columna='", df[i], "';", sep = "")
    out[i] <- dbGetQuery(con, SQL)
    dbDisconnect(con)
}

ИЛИ ЖЕ:

## Version ii
for(i in df) {
    SQL <- paste("SELECT max(ID) FROM table WHERE columna='", i, "';", sep = "")
    out[i] <- dbGetQuery(con, SQL)
    dbDisconnect(con)
}

То, что вы используете, будет зависеть от личного вкуса. Вторая (II) версия требует, чтобы вы установили имена на выходной вектор out которые совпадают с данными внутри out,

Сказав все это, предполагая, что ваш фактический SQL-запрос похож на тот, который вы публикуете, вы не можете сделать это в одном операторе SQL, используя GROUP BY пункт, чтобы сгруппировать данные перед вычислением max(ID)? Делать простые вещи в базе данных, как это, вероятно, будет гораздо быстрее. К сожалению, у меня нет экземпляра MySQL, и мой SQL-фу сейчас слаб, поэтому я не могу привести пример этого.

Вы также можете использовать sprintf Команда, чтобы решить проблему (это то, что я использую при создании Shiny Apps).

df <- c('a','b','c')

res <- dbGetQuery(con, sprintf("SELECT max(ID) FROM table WHERE columna='%s'"),df())

Что-то в этом роде должно работать.

Другие вопросы по тегам