5

我正在使用 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)

生成的 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

运行此代码会引发错误

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

但是ifelse查询按预期工作:

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

# check SQL code for query
show_query(tmp)

生成的 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

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

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

更新

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

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

更新 2

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

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

4

2 回答 2

0

只是你的 dplyr 语法有点错误吗?

尝试这个

# attempted query
tmp = my_table %>%
    mutate(new_col = case_when(col1 == col2 ~ "a",
                               col1 == 'TRUE' ~ "b"
              # alternatively  col1 == 1 ~ "b"
)) 
于 2018-08-23T07:24:06.887 回答
0

请参阅上面的更新 2:

这似乎是影响case_whenSQL 服务器的问题。

目前的解决方法是使用多个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
于 2018-09-13T21:23:28.710 回答