sql - 在 dbplyr SQL 查询中的 string::str_detect 中使用带有正则表达式的变量

标签 sql r regex dbi dbplyr

我想根据正则表达式是否出现在任何列中来过滤 SQL 数据库。我想将正则表达式指定为变量;但是它被读取为文字字符串。我无法将正则表达式作为变量输入。感谢您的帮助!

我查阅过的资源:

注意:我在使用 mtcars 数据集制作 reprex 时遇到了问题,遵循 https://www.tidyverse.org/blog/2018/01/dbplyr-1-2/ .我收到错误:“错误:str_detect() 在此 SQL 变体中不可用”。我无法使用我的实际 SQL 数据库共享 reprex。因此,下面是一个伪代表。

library(dplyr)
library(stringr)

# Variable with regex (either lower- or uppercase "m")
my_string <- "(?i)m"

# WITHOUT SQL DATABASE ----------------------------------------------------

# This runs
mtcars %>% 
  tibble::rownames_to_column() %>% 
  filter(str_length(rowname) > 5)

# This runs with STRING
mtcars %>% 
  tibble::rownames_to_column() %>% 
  filter(str_detect(rowname, "(?i)m"))

# This runs with VARIABLE
mtcars %>% 
  tibble::rownames_to_column() %>% 
  filter(str_detect(rowname, my_string))

# WITH SQL DATABASE -------------------------------------------------------

con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
mtcars_db <- copy_to(con, tibble::rownames_to_column(mtcars), "mtcars")

# This runs
tbl(con, "mtcars") %>% 
  filter(str_length(rowname) > 5)

# This *should* run with STRING -- pretend it does ;)
tbl(con, "mtcars") %>%
  filter(str_detect(rowname, "M"))

# This does NOT run with VARIABLE
tbl(con, "mtcars") %>%
  filter(str_detect(rowname, my_string))

最佳答案

这可能在很大程度上取决于您使用的 SQL 风格。 This问题提到了 str_detect 的翻译,还提供了一个替代方案。

SQL Server 测试:

library(dbplyr)
library(dplyr)
library(stringr)

data(mtcars)
df_sim = tbl_lazy(mtcars, con = simulate_mssql())
my_string <- "(?i)m"

df_sim %>%
  filter(str_detect(my_string, gear)) %>%
  show_query()
# Error: str_detect() is not available in this SQL variant

df_sim %>%
  filter(gear %like% my_string) %>%
  show_query()
# <SQL>
# SELECT *
# FROM `df`
# WHERE (`gear` like '(?i)m')

看来 str_detect 无法转换为 SQL Server。但您可以使用 %like% 作为解决方法。

MySQL 测试:

library(dbplyr)
library(dplyr)
library(stringr)

data(mtcars)
df_sim = tbl_lazy(mtcars, con = simulate_mysql()) # changed to mysql
my_string <- "(?i)m"

df_sim %>%
  filter(str_detect(my_string, gear)) %>%
  show_query()
# <SQL>
# SELECT *
# FROM `df`
# WHERE ('(?i)m' REGEXP `gear`)

df_sim %>%
  filter(gear %like% my_string) %>%
  show_query()
# <SQL>
# SELECT *
# FROM `df`
# WHERE (`gear` like '(?i)m')

看来 str_detect 可以为 MySQL 正确翻译。

在每种情况下,my_string 都会被翻译成查询。

还有一些其他的事情要检查:

  • 更新 dbplyr 的版本。旧版本没有新版本中的所有翻译。
  • 尝试使用行名以外的列。 R 中的数据框可以有行名,但 SQL 中的表只能有列。

关于sql - 在 dbplyr SQL 查询中的 string::str_detect 中使用带有正则表达式的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71208648/

相关文章:

mysql - 在 SQL 中获取总耗时 (TIME)

mysql - 有没有一个SQL命令可以通过id更新大量行?

r - 如何将列范围和行范围内的所有值相乘?

r - 更改循环中多个图的颜色

javascript - 传递 url 时保留原始反斜杠的问题

正则表达式 - 在匹配内容时删除前面和后面的空格

php - 如何使用 Group By 组合这两个 MySQL 查询

r - 查找加载的命名空间的库位置

python - 用于匹配除标点符号之外的所有非单词的正则表达式?

sql - 如果满足某些条件,如何将多个列设置为空?