SQL的dplyr是否可以在过滤器中将== NA转换为IS NULL?

时间:2019-04-01 10:33:13

标签: r dplyr dbplyr

我正在尝试使用dplyr查询SQL数据库,并匹配提供的参数。

  id <- tbl(conn, "My_Table") %>%
    filter(Elem1 == elem1 & Elem2 == elem2 & Elem3 == elem3) %>%
    select(Id) %>%
    collect()

但是,elem1elem2elem3中的任何一个都可能是NA。理想情况下,我希望查询将其转换为SQL IS NULL语句。

例如,如果elem1为1,elem2为NA,而elem3为3,我希望翻译后的查询为:

SELECT Id FROM My_Table WHERE Elem1 == 1 AND Elem2 IS NULL AND Elem3 == 3

但是,我上面的代码将where子句转换为... AND Elem2 == NULL ...,这显然不能满足我的要求。有解决这个问题的好方法吗?

1 个答案:

答案 0 :(得分:0)

假设您在SQL服务器中,则可以像这样使用COALESCE绕过此操作:

filler_value = -1

id <- tbl(conn, "My_Table") %>%
    mutate(Elem1 = COALESCE(Elem1, filler_value),
           Elem2 = COALESCE(Elem2, filler_value),
           Elem3 = COALESCE(Elem3, filler_value)) %>%
    filter(Elem1 == COALESCE(elem1, filler_value),
           Elem2 == COALESCE(elem2, filler_value),
           Elem3 == COALESCE(elem3, filler_value)) %>%
    select(Id) %>%
    collect()

在选择filler_value的地方,使其与数据集列具有相同的数据类型(文本/数字/日期),但不是当前出现在数据集列中的值。

COALESCE函数从其参数列表返回第一个非空值。因此,我们首先用占位符替换NULL列中的Elem_,然后用相同的占位符替换NULL值中的elem_。因此,标准的==比较是有意义的。

这里的关键思想之一是,由于COALESCE没有定义R到SQL的转换,因此当R代码转换为SQL时它会保留下来。有关更多详细信息/替代内容,请参见this问题。