16

如何使用 RSQLite 编写带有日期的 SQL 查询。下面是一个例子。dbGetQuery不返回任何行。

require(RSQLite)
require(ggplot2)
data(presidential)
m <- dbDriver("SQLite")
tmpfile <- tempfile('presidential', fileext='.db')
conn <- dbConnect(m, dbname=tmpfile)
dbWriteTable(conn, "presidential", presidential)
dbGetQuery(conn, "SELECT * FROM presidential WHERE Date(start) >= Date('1980-01-01')")
4

4 回答 4

13

只是为了说明,这很好用:

tmpfile <- tempfile('presidential', fileext='.db')
conn <- dbConnect(m, dbname=tmpfile)
p <- presidential
p$start <- as.character(p$start)
p$end <- as.character(p$end)

dbWriteTable(conn, "presidential", p)
dbGetQuery(conn, "SELECT * FROM presidential WHERE start >= '1980-01-01'")

您可以在此处的文档中了解 SQLite 中缺少原生日期类型的信息。我在 SQLite 中使用字符串作为日期已经很长时间了,以至于我实际上完全忘记了这个问题。

是的,我编写了一个小型 R 函数,可以将数据框中的任何 Date 列转换为字符。对于简单的比较,保留它们YYYY-MM-DD就足够了,如果我需要做算术,我会在 R 中的事实之后将它们转换。

于 2012-11-19T21:26:54.810 回答
1

继@joran 的回答之后,这是一个简单的函数,用于将日期列转换为 data.frame 的字符串。

mutate(df, across(where(is.Date), ~ format(.x, "%Y.%m.%d")))
于 2021-04-26T04:01:09.590 回答
1

我发现使用 RRSQLitedplyrSQLite 保持类型一致是最方便的方式。特别是,extendend_types = TRUE确保类型DATEDATETIME/TIMESTAMPTIME的列映射到相应的 R 类(至少在 2.2.8 版本之后RSQLite)。

library(dplyr)
library(RSQLite)
library(ggplot2)

data(presidential)

mydb <- dbConnect(SQLite(), "presidential.sqlite", extended_types = TRUE)
dbWriteTable(mydb, "presidential", presidential)

tbl(mydb, "presidential") %>% 
  filter(start >= as.Date("1980-01-01")) %>% 
  collect()

您还可以将后一个集合制定为 get 查询:

dbGetQuery(mydb, "SELECT * FROM presidential WHERE start >= CAST('1980-01-01' AS DATE)")
于 2021-12-22T16:47:05.983 回答
0

正如@joran 建议的那样,在 SQLlite 中以文本形式保存日期似乎是目前最好的方法。

我使用@Richard Knight 的方法进行转换,但使用 ISO 格式,在写入数据帧之前将日期更改为字符串:

local_df %>% mutate(across(where(lubridate::is.Date), ~ format(.x, "%Y-%m-%d")))

可以使用 sql 翻译远程操作日期,特别是:

remote_df %>% mutate(date_as_number = julianday(date_as_string))
remote_df %>% mutate(date_as_string = date(date_as_number))

Nbdate不在as.Date第二个中。这是因为as.Date将被转换为,CAST(date_as_number AS DATE)而我们想要的是使用 SQLLite 的date()函数和julianday().

可以自动将远程日期字符串映射回日期,如果您:

collect <- function(remote_df, ...) {
  raw = remote_df %>% dplyr::collect(...)
  isoDateString = function(x) return(is.character(x) & all(na.omit(stringr::str_detect(x,"[0-9]{4}-[0-9]{2}-[0-9]{2}"))) & !all(is.na(x)))
  raw = raw %>% mutate(across(where(isoDateString), ~ as.Date(.x, "%Y-%m-%d")))
  maybeJulian = function(x) {return(is.double(x) & all(na.omit(x>2440587.5)) & all(na.omit(x<2488069.5)) & !all(is.na(x)))}
  raw = raw %>% mutate(across(matches(".*(D|d)ate.*") & where(maybeJulian), ~ as.Date(.x-2440587.5, "1970-01-01")))
  return(raw)
}

函数中明显的随机数maybeJulian对应于1970-01-012100-01-01

于 2021-11-02T14:47:16.570 回答