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

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

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

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

【问题讨论】:

    标签: r database dplyr dbplyr


    【解决方案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 不同,其中处理逻辑可以通过管道清楚地分隔。但我不明白为什么这与从表中删除行有关。你在这里的真正意义是什么?你能用另一种方式解释吗?谢谢
    • 好点,我的第二个例子没有清楚地解决你的问题。我打算将它更多地提供给未来的读者,他们可能认为从远程表中删除行是比仅仅过滤掉它们更好的解决方案。我将编辑我的答案以使其更清楚。
    • 希望这些编辑使第二部分更加清晰。从您的问题看来,您打算修改数据库。因此,第二部分与您的答案不太相关,而更多的是尝试在未来证明答案。
    猜你喜欢
    • 1970-01-01
    • 2014-11-05
    • 2011-11-10
    • 2019-01-04
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    相关资源
    最近更新 更多