在 SQL 服务器中结合 dbplyr 和 case_when
Combining dbplyr and case_when in SQL Server
我正在使用 dbplyr 在 SQL 服务器中编写和 运行 查询,并希望应用条件变异。这可以使用 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
运行 此代码抛出错误
An expression of non-boolean type specified in a context where a condition is expected, near '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 查询吗?关于哪里出了问题以及如何解决这个问题有什么建议吗?
已更新
发布为 issue on the tidyverse and was informed that a solution has already been developed for case_when(..., TRUE ~ "b")
being translated to ELSE 'b'
(here)。
但是,因为这没有解决导致此异常的语法。编辑问题以关注引起问题的语法。
更新 2
作为 issue on dbplyr 发布。来自 Christophe Dervieux (cderv) 的响应表明原因似乎是 SQL 服务器需要对 case_when
进行特殊翻译,就像它对 ifelse
.
所做的一样
同时,用户可以使用多个 ifelse
或 if_else
语句。
是否只是您的 dplyr 语法有点错误?
试试这个
# attempted query
tmp = my_table %>%
mutate(new_col = case_when(col1 == col2 ~ "a",
col1 == 'TRUE' ~ "b"
# alternatively col1 == 1 ~ "b"
))
参见上面的更新 2:
这似乎是一个影响 SQL 服务器的 case_when
的问题。
目前的解决方法是使用多个 ifelse
或 if_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
我正在使用 dbplyr 在 SQL 服务器中编写和 运行 查询,并希望应用条件变异。这可以使用 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
运行 此代码抛出错误
An expression of non-boolean type specified in a context where a condition is expected, near '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 查询吗?关于哪里出了问题以及如何解决这个问题有什么建议吗?
已更新
发布为 issue on the tidyverse and was informed that a solution has already been developed for case_when(..., TRUE ~ "b")
being translated to ELSE 'b'
(here)。
但是,因为这没有解决导致此异常的语法。编辑问题以关注引起问题的语法。
更新 2
作为 issue on dbplyr 发布。来自 Christophe Dervieux (cderv) 的响应表明原因似乎是 SQL 服务器需要对 case_when
进行特殊翻译,就像它对 ifelse
.
同时,用户可以使用多个 ifelse
或 if_else
语句。
是否只是您的 dplyr 语法有点错误?
试试这个
# attempted query
tmp = my_table %>%
mutate(new_col = case_when(col1 == col2 ~ "a",
col1 == 'TRUE' ~ "b"
# alternatively col1 == 1 ~ "b"
))
参见上面的更新 2:
这似乎是一个影响 SQL 服务器的 case_when
的问题。
目前的解决方法是使用多个 ifelse
或 if_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