создание зацикленного SQL-запроса с использованием RODBC в R - PullRequest
0 голосов
/ 03 января 2019

В первую очередь - спасибо, что нашли время, чтобы посмотреть на мой вопрос, независимо от того, отвечаете вы или нет!

Я пытаюсь создать функцию, которая просматривает мой df и запрашивает необходимые данныеиз SQL с использованием пакета RODBC в R. Однако у меня возникают проблемы при настройке запроса, так как параметр запроса меняется на каждой итерации (пример ниже)

Так что мой df выглядит так:

     ID     Start_Date    End_Date    
     1       2/2/2008      2/9/2008
     2       1/1/2006      1/1/2007
     1       5/7/2010      5/15/2010
     5       9/9/2009      10/1/2009

Как мне указать дату начала и дату окончания в моей программе sql?

вот что у меня есть:

 data_pull <- function(df) {
    a <- data.frame()
    b <- data.frame()

    for (i in df$id)
{ 
    dbconnection <- odbcDriverConnect(".....")

    query <- paste("Select ID, Date, Account_Balance from Table where ID = (",i,") and Date > (",df$Start_Date,") and Date <= (",df$End_Date,")")

    a <- sqlQuery(dbconnection, paste(query))
    b <- rbind(b,a)
 }
  return(b)
 }

Однако это ни к чему не приводит.Я считаю, что это как-то связано с тем, как я указываю дату начала и окончания итерации.

Если кто-то может помочь в этом, это было бы очень признательно.Если вам нужны дальнейшие объяснения, пожалуйста, не стесняйтесь спрашивать!

1 Ответ

0 голосов
/ 03 января 2019

При текущей настройке возникает пара проблем с синтаксисом:

  1. LOOP: Вы не выполняете итерацию по всем строкам фрейма данных, а только значения атомарного идентификатора в одном столбце, df$ID.В этом же цикле вы передаете целые векторы df$Start_Date и df$End_Date в конкатенацию запросов.

  2. ДАТЫ: форматы даты не соответствуют большинствубаза данных в форматах даты «ГГГГ-ММ-ДД».И, тем не менее, некоторые другие, такие как Oracle, требуют преобразования строки в данные: TO_DATE(mydate, 'YYYY-MM-DD').

Пара вышеупомянутых проблем производительности / передового опыта:

ПАРАМЕТРИЗАЦИЯ: хотя параметризация не требуется по соображениям безопасности, поскольку ваши значения не генерируются пользовательским вводом, который может внедрить вредоносный код SQL, для удобства обслуживания и читабельности рекомендуется параметризованные запросы.Следовательно, подумайте об этом.

РАСТУЩИЕ ОБЪЕКТЫ: Согласно Inferno Патрика Берна * Круг 2: Растущие объекты , программисты R должны избегать растущих мульти-мерные объекты, такие как фреймы данных внутри цикла, которые могут вызвать чрезмерное копирование в памяти.Вместо этого создайте список фреймов данных для rbind один раз вне цикла.


При этом вы можете избежать любых циклических или листинговых потребностейсохраняя ваш фрейм данных в виде таблицы базы данных, затем присоединяйте к финальной таблице для отфильтрованного запроса на присоединение к импорту.Предполагается, что пользователь вашей базы данных имеет привилегии CREATE TABLE и DROP TABLE.

# CONVERT DATE FIELDS TO DATE TYPE
df <- within(df, {
          Start_Date = as.Date(Start_Date, format="%m/%d/%Y")
          End_Date = as.Date(End_Date, format="%m/%d/%Y")
})

# SAVE DATA FRAME TO DATABASE
sqlSave(dbconnection, df, "myRData", rownames = FALSE, append = FALSE)

# IMPORT JOINED AND DATE FILTERED QUERY
q <- "SELECT ID, Date, Account_Balance 
      FROM Table t
      INNER JOIN myRData r 
        ON r.ID = t.ID 
        AND t.Date BETWEEN r.Start_Date AND r.End_Date"

final_df <- sqlQuery(dbconnection, q)
...