我正在使用 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
.
同时,用户可以使用多个ifelse
orif_else
语句。