【问题标题】:How to use custom SQL function in dbplyr?如何在 dbplyr 中使用自定义 SQL 函数?
【发布时间】:2018-11-12 16:25:04
【问题描述】:

我想计算数据库中的 Jaro-Winkler 字符串距离。如果我将数据带入 R(使用 collect),我可以轻松使用 stringdist 包中的 stringdist 函数。

但我的数据非常大,我想在将数据拉入 R 之前过滤 Jaro-Winkler 距离。

有 Jaro-Winkler 的 SQL 代码(https://androidaddicted.wordpress.com/2010/06/01/jaro-winkler-sql-code/T-SQL 的版本),但我想我不确定如何最好地让该 SQL 代码与 dbplyr 一起工作。我很高兴尝试将 stringdist 函数映射到 Jaro-Winkler sql 代码,但我不知道从哪里开始。但即使是像直接从 R 对远程数据执行 SQL 代码这样更简单的事情也会很棒。

我曾希望 dbplyr 文档中的 SQL translation 可能会有所帮助,但我不这么认为。

【问题讨论】:

  • 您能否提供一个包含示例数据代码的最小、完整、可验证的示例? stackoverflow.com/help/mcve
  • 您可以直接进行 SQL 调用并在您的数据进入后使用 dplyr 吗?

标签: r stringdist dbplyr


【解决方案1】:

您可以在 R 中构建自己的 SQL 函数。它们只需生成一个有效的 SQL 查询字符串。我不知道 Jaro-Winkler 距离,但我可以提供一个示例供您构建:

union_all = function(table_a,table_b, list_of_columns){
  # extract database connection
  connection = table_a$src$con

  sql_query = build_sql(con = connection,
                      sql_render(table_a),
                      "\nUNION ALL\n",
                      sql_render(table_b)
  )

  return(tbl(connection, sql(sql_query)))
}

unioned_table = union_all(table_1, table_2, c("who", "where", "when"))

这里有两个关键命令:

  • sql_render,它接受一个 dbplyr 表并返回生成它的 SQL 代码
  • build_sql,从字符串中组装查询。

您可以选择执行命令:

  • tbl(connection, sql(sql_query)) 将返回结果表
  • dbExecute(db_connection, as.character(sql_query)) 将执行查询而不返回结果(用于删除表、创建索引等)

【讨论】:

  • 我已经试用了您的解决方案并且它有效。但我为一件事感到困扰:第一次 dbplyr 通过table_a <-tbl(con, "table_a") 连接到数据库时,它需要执行一个虚拟查询,即“select * from table_a where 0 = 1”。如果我现在在 sql_render/build_sql 中使用 R 对象 table_a,它将再次执行相同类型的 WHERE 0 = 1 查询。有没有办法阻止 dbplyr 这样做,而是重用第一个 tbl(...) 调用中的元数据?
  • 我已经看到 dbplyr 生成包含 WHERE 0 = 1 的 SQL 查询,但它们从未影响我的自定义 SQL 函数。这可能是由于您连接到 SQL 表的方式,或者因为您调用 render_sql(tbl(con, "table_a")) 而不是在调用 render_sql(tbl_a) 之前先分配 tbl_a = tbl(con, "table_a")。但我无法从你提供的细节中看出。考虑打开一个新问题并在此处发布指向它的链接 - 我可以更详细地查看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
  • 2020-02-01
相关资源
最近更新 更多