dbplyr:从数据库中的表中删除行

Posted

技术标签:

【中文标题】dbplyr:从数据库中的表中删除行【英文标题】:dbplyr: delete row from a table in database 【发布时间】:2022-01-20 12:01:00 【问题描述】:

等价于DBI::dbSendQuery(con, "DELETE FROM <table> WHERE <condition>")的dbplyr动词组合是什么。

我想要的不是从数据库中查询数据,而是从数据库中删除数据并更新表。

我想以dplyr 的方式进行,但我不确定是否可行。我在包参考中找不到类似的东西。

【问题讨论】:

【参考方案1】:

dbplyr 将 dplyr 命令转换为查询数据库表。我不知道使用纯 dbplyr 修改现有数据库表的任何内置方法。

这可能是一种设计选择。

在 R 中,我们不需要区分从表中获取数据(查询)和修改表。这可能是因为在 R 中,如果发生错误/错误,我们可以将原始数据重新加载到内存中。 但在数据库中查询和修改表是故意不同的事情。修改数据库时,您正在修改源,因此使用了额外的控件(因为恢复已删除的数据要困难得多)。

DBI包可能是你修改数据库的最佳选择

这是我用于所有 dbplyr 工作的方法。通常是一个自定义函数,它接受由 dbplyr 翻译产生的查询并将其插入到 DBI 调用中(您可以在我的 dbplyr helpers GitHub 存储库中看到这方面的示例)。

为此考虑两种方法:(1) 反连接(在所有列上)然后编写一个新表,(2) DELETE FROM 语法。

反连接方法的模拟

records_to_remove = remote_table %>%
  filter(conditions)

desired_final_table = remote_table %>%
  anti_join(records_to_remove, by = colnames(remote_table))

query = paste0("SELECT * INTO output_table FROM (",
               sql_render(desired_final_table),
               ") AS subquery")

DBI::dbExecute(db_con, as.character(query))

DELETE FROM 语法模拟

records_to_remove = remote_table %>%
  filter(conditions)

query = sql_render(records_to_remove) %>%
  as.character() %>%
  gsub(search_term = "SELECT *", replacement_term = "DELETE")

DBI::dbExecute(db_con, query)

如果您计划多次运行这些查询,则建议将它们包装在一个函数中,并检查有效性。

对于某些用例,不需要删除行。

您可以将 R 中的filter 命令视为从表中删除 行。例如在 R 中我们可能会运行:

prepared_table = input_table %>%
  filter(colX == 1) %>%
  select(colA, colB, colZ)

并将其视为在产生输出之前删除 colX == 1 所在的行:

output = prepared_table %>%
  group_by(colA) %>%
  summarise(sumZ = sum(colZ))

(或者您可以使用上面的反连接代替过滤器。)

但是对于这种类型的删除,您不需要编辑源数据,因为您每次都可以在运行时过滤掉不需要的行。是的,它会使您的数据库查询更大,但这对于使用数据库来说是正常的。

所以结合SQL中的准备和输出是正常的(大概是这样的):

SELECT colA, SUM(colZ) AS sumZ
FROM (

  SELECT colA, colB, colZ
  FROM input_table
  WHERE colX = 1

) AS prepared_table
GROUP BY colA

所以除非你需要修改数据库,否则我建议过滤而不是删除。

【讨论】:

感谢您的全面回答。对于您答案的第二部分。我了解在 SQL 中,查询通常与多个逻辑组合,包括 group by 和使用 where 语句进行过滤,这与 dplyr 不同,其中处理逻辑可以通过管道清楚地分隔。但我不明白为什么这与从表中删除行有关。你在这里的真正意义是什么?你能用另一种方式解释吗?谢谢 好点,我的第二个例子没有清楚地解决你的问题。我打算将它更多地提供给未来的读者,他们可能认为从远程表中删除行是比仅仅过滤掉它们更好的解决方案。我将编辑我的答案以使其更清楚。 希望这些编辑使第二部分更加清晰。从您的问题看来,您打算修改数据库。因此,第二部分与您的答案不太相关,而更多的是尝试在未来证明答案。

以上是关于dbplyr:从数据库中的表中删除行的主要内容,如果未能解决你的问题,请参考以下文章

如何删除EXCEL表中的大量数据行,要删除的行数大概8万

将 purrr::map2() 与 dbplyr 一起使用

如何从 DbVisualizer 中删除表中的重复行

如何在 SAP ASE Sybase 16 中从具有外键的表中删除行

如何从雪花数据库中的表中删除前 N 条记录

sql怎么删除一个表中的所有数据