在 SQL Server 中结合 dbplyr 和 case_when

Sim*_*.A. 5 sql-server r dbplyr

我正在使用 dbplyr 在 SQL Server 中编写和运行查询,并希望应用条件突变。这可以通过使用ifelse或使用来完成case_when。查询在使用时有效,ifelse但在使用时抛出和异常case_when

问题似乎是这两个命令被翻译成的 SQL 语法。该case_when语法不似乎是有效的SQL。你能告诉我为什么以及如何解决它吗?或者这是一个错误?

# libraries
library(DBI)
library(dplyr)
library(dbplyr)

# establish connection to database table
connection_string = "database.specific.string"
# mine looks something like "DRIVER=...; Trusted_Connection=...; DATABASE=...' SERVER=..."
db_connection = dbConnect(odbc::odbc(), .connection_string = connection_string)
my_table = tbl(db_connection, from = my_table_name)

# attempted query
tmp = my_table %>%
    mutate(new_col = case_when(col1 == col2 ~ "a",
                               col1 != col2 ~ "b"))

# check SQL code for query
show_query(tmp)
Run Code Online (Sandbox Code Playgroud)

生成的 SQL 查询是:

SELECT 
    col1, col2,
    CASE
       WHEN CONVERT(BIT, IIF(col1 = col2, 1.0, 0.0))) THEN ('a')
       WHEN CONVERT(BIT, IIF(col1 <> col2, 1.0, 0.0))) THEN ('b')
    END AS new_col
FROM my_database.my_table_name
Run Code Online (Sandbox Code Playgroud)

运行此代码会引发错误

在预期条件的上下文中指定的非布尔类型的表达式,靠近“THEN”

但是ifelse查询按预期工作:

# attempted query
tmp = my_table %>%
    mutate(new_col = ifelse(col1 == col2, "a", "b"))

# check SQL code for query
show_query(tmp)
Run Code Online (Sandbox Code Playgroud)

生成的 SQL 查询是:

SELECT 
    col1, col2,
    CASE
       WHEN (CONVERT(BIT, IIF(col1 = col2, 1.0, 0.0))) = TRUE) THEN ('a')
       WHEN (CONVERT(BIT, IIF(col1 = col2, 1.0, 0.0))) = FALSE) THEN ('b')
    END AS new_col
FROM my_database.my_table_name
Run Code Online (Sandbox Code Playgroud)

请注意,在这两种情况下,SQL 语法都是使用show_query. 使用translate_sql始终产生生产更清洁的SQL语法的SQL代码,但是这不是获取服务器上运行的语法。

有没有其他人得到这些 SQL 查询?关于什么是错的以及如何解决这个问题的任何建议?

更新

在 tidyverse 上作为问题发布,并被告知已经开发了一个解决方案以case_when(..., TRUE ~ "b")翻译到ELSE 'b'此处)。

但是,因为这并没有解决导致此异常的语法。问题已编辑,重点关注作为原因的语法。

更新 2

在 dbplyr 上作为问题发布。来自 Christophe Dervieux (cdrv) 的回复表明原因似乎是 SQL Server 需要一个特殊的翻译,case_when就像它对ifelse.

同时,用户可以使用多个ifelseif_else语句。

Sim*_*.A. 0

请参阅上面的更新 2:

这似乎是影响case_whenSQL Server 的问题。

目前的解决方法是使用多个ifelseorif_else语句:

data %>%
    mutate(new_col = ifelse(condition1, val1, NA)) %>%
    mutate(new_col = ifelse(is.na(new_col) & condition2, val2, new_col)) %>%
    mutate(new_col = ifelse(is.na(new_col) & condition3, val3, new_col))
    # etc
Run Code Online (Sandbox Code Playgroud)