将现有和不存在的数据框混合插入到 sql

Posted

技术标签:

【中文标题】将现有和不存在的数据框混合插入到 sql【英文标题】:Insert mix of existing and non-existing data frame to sql 【发布时间】:2015-10-29 07:41:53 【问题描述】:

我想使用 R 和 RODBC 将预测数据写入 sql-server。每个预测都是针对接下来的六个小时,我只想保存每个预测的最新一代。此处说明:

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"。但下一次我可能无法做到。

【问题讨论】:

不熟悉t-sql。您可以在Dates 列上添加主键吗?然后,您可以在两个查询中使用INSERT,并且引擎(也许)应该自动更新重复的Dates 值。 那不行 :) 日期已经是关键了。 【参考方案1】:

您可以尝试先进行条件插入,然后进行更新,条件插入意味着您仅在 Date 尚不存在且更新始终成功时才插入(如果成功插入值,则进行一些不必要的更新)

条件插入类似于以下内容:

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')

【讨论】:

以上是关于将现有和不存在的数据框混合插入到 sql的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 插入、选择和不存在

如何将 R 数据框插入到 SQL Server 中的现有表中

插入和不存在的插入之间的性能差异

如果数组不存在,则从现有 URL 将数组插入到页面链接 url 中创建数组,将默认值插入到页面上的 href 链接中

从 Python 到 SQL(Aginity、Netezza)的 CREATE/DROP 调用不起作用

SQL Server 如果存在