【问题标题】:When filtering an SQLite database with dplyr, should `|` be avoided?使用 dplyr 过滤 SQLite 数据库时,是否应该避免使用 `|`?
【发布时间】:2015-01-29 00:45:40
【问题描述】:

在 R 中使用 dplyr 过滤 SQLite 数据库时遇到了一些意外行为。以下是我看到的示例:

library(dplyr)

# Some test data
df <- tbl_df(data.frame(
  v1 = c('a', 'b', 'a', 'b'),
  v2 = c('b', 'a', 'a', 'b'),
  v3 = month.abb[1:4]))

db <- copy_to(src_sqlite('example.sqlite', create = TRUE), df)

filter(df, v1 == 'a' | v2 == 'a', v3 == 'Jan') 
# Source: local data frame [1 x 3]
#
#   v1 v2  v3
# 1  a  b Jan

filter(db, v1 == 'a' | v2 == 'a', v3 == 'Jan')
# Source: sqlite 3.8.6 [example.sqlite]
# From: df [2 x 3]
# Filter: v1 == "a" | v2 == "a", v3 == "Jan" 
#
#  v1 v2  v3
# 1  a  b Jan
# 2  a  a Mar

我对使用数据库非常陌生,所以我觉得我在这里遗漏了一些与在过滤器中使用 | 有关的明显内容,因为这可以按预期工作:

filter(db, v1 == 'a', v3 == 'Jan') 
# Source: sqlite 3.8.6 [example.sqlite]
# From: df [1 x 3]
# Filter: v1 == "a", v3 == "Jan" 
#
#   v1 v2  v3
# 1  a  b Jan

在使用 dplyr 处理数据库时是否应该避免使用 |

更新: dplyr issue #934

【问题讨论】:

    标签: r sqlite filter dplyr


    【解决方案1】:

    如果你这样做

    filter(db, v1 == 'a' | v2 == 'a', v3 == 'Jan') %>% show_query()
    

    你会看到它变成了

    <SQL>
    SELECT "v1", "v2", "v3"
    FROM "df"
    WHERE "v1" = 'a' OR "v2" = 'a' AND "v3" = 'Jan'
    

    所以| 被翻译成OR,但第一个“术语”并没有放在一起。那么由于 AND 的优先级比 OR 高,就和运行一样

    WHERE "v1" = 'a' OR ("v2" = 'a' AND "v3" = 'Jan')
    

    您可以添加自己的括号来避免问题

    filter(db, (v1 == 'a' | v2 == 'a'), v3 == 'Jan') %>% show_query()
    # <SQL>
    # SELECT "v1", "v2", "v3"
    # FROM "df"
    # WHERE ("v1" = 'a' OR "v2" = 'a') AND "v3" = 'Jan'
    
    filter(db, (v1 == 'a' | v2 == 'a'), v3 == 'Jan')
    # Source: sqlite 3.8.6 [example.sqlite]
    # From: df [1 x 3]
    # Filter: (v1 == "a" | v2 == "a"), v3 == "Jan" 
    # 
    #   v1 v2  v3
    # 1  a  b Jan
    

    如果您在 SQL 的情况下有多个条件,我不确定为什么 dplyr 不会为您隐式添加括号,因为它似乎确实在为 data.frame 正确评估它们。你可以考虑filing this as an "issue" 看看官方对此的立场是什么,因为在我看来它看起来像一个错误。

    【讨论】:

    • 这绝对是一个错误
    猜你喜欢
    • 2011-08-31
    • 2019-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多