5

我有一个非常简单的问题会产生错误。示例将清除这一点。

library(odbc)
library(DBI)
library(dplyr)
library(dbplyr)

con <- dbConnect(odbc(), "myDSN")

tbl_test <- tibble(ID = c("A", "A", "A", "B", "B", "B"),
                   val = c(1, 2, 3, 4, 5, 6),
                   cond = c("H", "H", "A", "A", "A", "H"))

dbWriteTable(con, "tbl_test", tbl_test, overwrite = TRUE)

在将简单表写入 DB 后,我在 db 中添加了指向表的链接,并尝试使用正常工作的简单条件和。但会面临错误。

db_tbl <- tbl(con, in_schema("dbo", "tbl_test"))

db_tbl %>% 
  group_by(ID) %>% 
  summarise(sum = sum(val, na.rm = TRUE),
            count_cond = sum(cond == "H", na.rm=TRUE),
            sum_cond = sum(val == "H", na.rm=TRUE))

Error: <SQL> 'SELECT  TOP 10 "ID", SUM("val") AS "sum", SUM(CONVERT(BIT, IIF("cond" = 'H', 1.0, 0.0))) AS "count_cond", SUM(CONVERT(BIT, IIF("val" = 'H', 1.0, 0.0))) AS "sum_cond"
FROM dbo.tbl_test
GROUP BY "ID"'
  nanodbc/nanodbc.cpp:1587: 42000: [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Operand data type bit is invalid for sum operator.

我不是专家,但感觉 SQL 无法将 TRUE 理解为 1,因此无法计算总和。周围有没有,因为很多时候我面临某种情况。下面只是普通 tibble 的代码,以表明它们应该可以工作。

tbl_test %>% 
  group_by(ID) %>% 
  summarise(sum = sum(val),
            count_cond = sum(cond == "H"),
            sum_cond = sum(val[cond == "H"]))

# A tibble: 2 x 4
  ID      sum count_cond sum_cond
  <chr> <dbl>      <int>    <dbl>
1 A        6.          2       3.
2 B       15.          1       6.

我知道这可能不是可重现的示例,因为并非每个人都有可用的数据库连接。

4

1 回答 1

7

SQL Server 不能对布尔值求和(它不会强制TRUE1)。

所以你必须手动转换它们,一种方法是使用ifelse,你的代码变成:

db_tbl %>%
  group_by(ID) %>% 
  summarise(sum = sum(val, na.rm=TRUE), 
            count_cond = sum(ifelse(cond == "H",1,0),na.rm=TRUE),
            sum_cond = sum(ifelse(cond == "H",val,0),na.rm=TRUE))
于 2018-04-01T12:56:41.360 回答