12

我需要在某些PostgreSQL数据库表中的其他列上条件更新列值。我设法在 R 中编写了一条 SQL 语句并使用dbExecutefrom DBIpackage 执行它。

library(dplyr)
library(DBI)

# Establish connection with database
con <- dbConnect(RPostgreSQL::PostgreSQL(), dbname = "myDb",
                 host="localhost", port= 5432, user="me",password = myPwd)

# Write SQL update statement
request <- paste("UPDATE table_to_update",
                 "SET var_to_change = 'new value' ",
                 "WHERE filter_var = 'filter' ")

# Back-end execution
con %>% dbExecute(request)

dplyr是否可以仅使用语法来做到这一点?出于好奇,我尝试过,

con %>% tbl("table_to_update") %>%
   mutate(var_to_change = if (filter_var == 'filter') 'new value' else var_to_change)

它在 R 中有效,但显然在 db 中没有任何作用,因为它使用了一个select语句。copy_to只允许appendoverwite选项,所以我看不到如何使用它,除非删除然后附加过滤后的观察结果......

4

1 回答 1

5

当前的 dplyr 0.7.1(带有 dbplyr 1.1.0)不支持这一点,因为它假定所有数据源都是不可变的。发行UPDATE通孔dbExecute()似乎是最好的选择。

要替换表中较大的块,您还可以:

  1. 通过 将数据框写入数据库中的临时表copy_to()
  2. 开始交易。
  3. 发出一个DELETE FROM ... WHERE id IN (SELECT id FROM <temporary table>)
  4. 发出一个INSERT INTO ... SELECT * FROM <temporary table>
  5. 提交交易

根据您的架构,您可能可以使用 singleINSERT INTO ... ON CONFLICT DO UPDATE而不是DELETEthen INSERT

于 2017-07-17T19:42:16.177 回答