2015-10-29 4 views
2

Я хотел бы написать прогнозные данные в sql-сервер, используя R и RODBC. Каждый прогноз рассчитан на следующие шесть часов, и я хотел бы сохранить только новое поколение каждого foreacst. Иллюстрированный здесь:Вставить смесь существующего и несуществующего фрейма данных в sql

set.seed(1) 
# First forecast at 00:00:00 
df.0 <- data.frame(Dates = seq.POSIXt(from = as.POSIXct("2015-10-29 00:00:00"), 
             to = as.POSIXct("2015-10-29 5:00:00"), by = "hour"), 
        Value = runif(6, min = 0, max = 6)) 

# Second forecast at 01:00:00 
df.1 <- data.frame(Dates = seq.POSIXt(from = as.POSIXct("2015-10-29 01:00:00"), 
             to = as.POSIXct("2015-10-29 6:00:00"), by = "hour"), 
        Value = runif(6, min = 0, max = 6)) 

Теперь, 00:00:00 я бы сохранить свой первый прогноз в базу dbdata мои данные:

require(RODBC) 

sqlSave(channel = dbdata, data = df.0, tablename = "forecasts", 
append = TRUE, rownames = FALSE, fast = FALSE, verbose = TRUE) 

# Query: INSERT INTO "forecast" ("Dates", "Values") VALUES 
('2015-10-29 00:00:00', '1.59') 
# Query: INSERT INTO "forecast" ("Dates", "Values") VALUES 
('2015-10-29 00:00:00', '2.23') 
# etc for all 6 forecasts 

Теперь, 01:00:00 получить новый прогноз. Я хочу сохранить/обновить этот прогноз, поэтому я заменяю все значения от 01:00:00 to 05:00:00 и добавляю самый новый прогноз на 06:00:00.

Обновление работает хорошо - поэтому я могу перезаписать файлы, но обновление не может вставить последний прогноз 06:00:00.

sqlUpdate(channel = dbdata, dat = df.1, tablename = "forecasts", 
fast = FALSE, index = c("Dates"), verbose = TRUE) 

# Query: UPDATE "forecast" SET "Value" = 5.668 WHERE "Dates" = '2015-10-29 00:01:00' 
# etc. until 
# Error in sqlUpdate(channel = prognoser, dat = df.1[, ], 
# table = "forecast", : 
# [RODBC] ERROR: Could not SQLExecDirect 
# 'UPDATE " "forecast" SET "Value" = 1.059 WHERE "Dates" = '2015-10-29 06:00:00' 

Таким образом, это может быть, вероятно, будет решена много способов - но каковы хорошие способы, чтобы сделать это?

Я думаю, что должны быть лучшие способы, чем читать таблицу и выяснить, как долго находится прогноз в базе данных. Затем разделите новые данные на обновленную и сохраненную часть и напишите их.

Это серверный сервер t-sql. Таблицы находятся в одной базе данных, но это чистое совпадение. Это означает, что: RODBC: merge tables from different databases (channel) не должно быть проблемой, и, возможно, я смогу уйти с t-sql "MERGE INTO". Но в следующий раз я, вероятно, не смогу.

+0

Не знакомы с 'т-sql'. Можете ли вы добавить первичный ключ в столбец «Даты»? Затем вы можете использовать 'INSERT' в обоих запросах, и механизм (возможно) автоматически должен обновлять повторяющиеся значения« Даты ». – nicola

+0

Это не сработает :) Даты уже являются ключом. – NoThanks

ответ

0

Вы можете попробовать сделать условную вставку с последующим обновлением, условная вставка означает, что вы только вставить если дата еще не существует, и обновление всегда успешно (вы делаете некоторые ненужные обновления, если значение было успешно установлены)

Что-то вроде следующего для условной вставки:

INSERT INTO "forecast" ("Dates", "Values") VALUES ('2015-10-29 00:00:00', '2.23') where not exists (select 1 from "forecast" where "Dates"='2015-10-29 00:00:00')