Question

    

Cette question a déjà une réponse ici:

    
            
  •              dynamique « string » en R                                      2 réponses                          
  •     
    

Est-il possible de passer une valeur dans la requête dans dbGetQuery du package rmysql.

Par exemple, si j'ai un ensemble de valeurs dans un vecteur de caractères:

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

Et je veux faire une boucle à travers les valeurs de tirer une valeur spécifique à partir d'une base de données pour chacun.

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

Lorsque je tente d'ajouter la référence à la valeur que je reçois une erreur. Vous vous demandez s'il est possible d'ajouter une valeur à partir d'un objet R dans la requête.

Était-ce utile?

La solution

Une option consiste à manipuler la chaîne SQL dans la boucle. Au moment où vous avez un littéral de chaîne, le 'df[2]' est pas interprété par R comme autre chose que des caractères. Il va y avoir des ambiguïtés dans ma réponse, parce que df dans votre Q est manifestement pas une trame de données (il est un vecteur de caractère!). Quelque chose comme cela va faire ce que vous voulez.

Rangez la sortie dans un vecteur numérique:

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

Maintenant, nous pouvons boucler sur les éléments de df pour exécuter votre requête trois fois. Nous pouvons régler la boucle de deux façons différentes: i) avec i comme un certain nombre que nous utilisons pour référencer les éléments de df et out, ou ii) avec i que chaque élément de df à son tour (c.-à-a, puis b, ... ). Je vais montrer les deux versions ci-dessous.

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

OU:

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

que vous utilisez dépendra de goût personnel. La deuxième (ii) La version exige des noms sur le vecteur ensemble de sortie out qui sont les mêmes que les données à l'intérieur out.

Ceci étant dit, en supposant que votre requête SQL réelle est similaire à celui que vous publiez, ne peut pas vous faire en une seule instruction SQL, en utilisant la clause GROUP BY, pour regrouper les données avant de calculer max(ID)? Faire des choses simples dans la base de données comme celui-ci sera probablement beaucoup plus rapide. Malheureusement, je n'ai pas une instance de MySQL autour de jouer avec et mon SQL-fu est faible actuellement, donc je ne peux pas donner un exemple de cela.

Autres conseils

Vous pouvez également utiliser la commande sprintf pour résoudre le problème (c'est ce que je l'utilise lors de la construction Shiny Apps).

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

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

Quelque chose le long de ces lignes devrait fonctionner.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top