Aggiungere un valore dinamico in RMySQL getQuery [duplicato]
Domanda
Questa domanda ha già una risposta qui:
- dinamico “stringa” in R 2 risposte
E 'possibile passare un valore nella query in dbGetQuery
dal pacchetto RMySQL.
Per esempio, se ho un insieme di valori in un vettore di carattere:
df <- c('a','b','c')
E voglio un ciclo tra i valori a tirare fuori un valore specifico da un database per ogni.
library(RMySQL)
res <- dbGetQuery(con, "SELECT max(ID) FROM table WHERE columna='df[2]'")
Quando provo ad aggiungere il riferimento al valore ottengo un errore. Chiedendosi se è possibile aggiungere un valore da un oggetto R nella query.
Soluzione
Una possibilità è quella di manipolare la stringa SQL all'interno del ciclo. Al momento si dispone di un letterale stringa, il 'df[2]'
non viene interpretata da R come qualcosa di diverso caratteri. Ci stanno per essere alcune ambiguità nella mia risposta, perché df
nella vostra Q non è palesemente un frame di dati (si tratta di un vettore di carattere!). Qualcosa di simile a questo farà quello che vuoi.
memorizzare l'output in un vettore numerico:
require(RMySQL)
df <- c('a','b','c')
out <- numeric(length(df))
names(out) <- df
Ora possiamo ciclo sugli elementi di df
per eseguire la query per tre volte. Possiamo impostare il circuito due modi: i) con i
come un numero che usiamo per riferimento agli elementi di df
e out
, oppure ii) con i
quale ciascun elemento di df
a sua volta (cioè a
, quindi b
, ... ). Vi mostrerò entrambe le versioni inferiori.
## 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)
}
O:
## Version ii
for(i in df) {
SQL <- paste("SELECT max(ID) FROM table WHERE columna='", i, "';", sep = "")
out[i] <- dbGetQuery(con, SQL)
dbDisconnect(con)
}
Il che si usa dipende dal gusto personale. Il secondo (ii) la versione richiede di nomi dei set sul out
uscita vettore che sono gli stessi in quanto i dati all'interno out
.
Detto questo, supponendo che il reale query SQL è simile a quello di pubblicare, non si può fare questo in una singola istruzione SQL, utilizzando la clausola GROUP BY
, per raggruppare i dati prima di calcolare max(ID)
? Fare le cose semplici nella base di dati come questo sarà probabilmente molto più veloce. Purtroppo, non ho un'istanza MySQL in giro a giocare con il mio SQL-fu è debole al momento, quindi non posso dato un esempio di questo.
Altri suggerimenti
È anche possibile utilizzare il comando sprintf
per risolvere il problema (che è quello che uso quando si costruisce Shiny Apps).
df <- c('a','b','c')
res <- dbGetQuery(con, sprintf("SELECT max(ID) FROM table WHERE columna='%s'"),df())
Qualcosa del genere dovrebbe funzionare.