使 SQLite 的 generate_sequence 能够在 MS windows 下的 R 的 sqldf 库中使用

enabling SQLite's generate_sequence to be used in R's sqldf library under MS windows

我希望在 R 的 sqldf 库中使用 SQLite3 的 generate_series Table-Valued Function,而后者又使用 RSQLite 库。我希望一旦 installed/configured,我就可以将其称为:

sqldf('SELECT value FROM generate_series(5,100,5)')

来自阅读Run-Time Loadable Extensions, I understand I will need to first call load_extension(X),具体为

sqldf('select load_extension("C:\my\path\to\sqlite\pathext\misc\series.c")')

但是,我也读到了 Extension loading is off by default,但我不知道如何在 sqldf 调用中打开它。这可能吗?我是否必须使用此默认切换来编译我自己的 sqlite3?

此外,我想确认 Compiling A Loadable Extension myself with MinGW, because apparently without compiling ext/misc/series.c, I will find that SQLite generate_series is missing, and none of the Downloads 没有提供编译的快捷方式。

如果我没理解错,我就不必compile all of SQLite,我可以将下载的版本与我编译的扩展一起使用。

最后,我如何确保 sqldf / RSQLite 选择的 sqlite3 版本是我配置的版本?这会迫使我自己编译 RSQLite 而不是简单地 install.packages(c('RSQLite')) 吗?

所有这一切似乎只是为了这个扩展而做的很多工作。有更好的方法吗?

感谢您的帮助!

建议您提交 issue on the RSQLite github site 以添加它,但与此同时这里有一些解决方法,不涉及重新构建 SQLite 和 RSQLite。

1) 递归 CTE 这可以在不使用 CTE 的扩展的情况下完成,如 https://www.sqlite.org/series.html 中所示。

具体试试这个 sqldf 代码:

library(sqlite)

start <- 1
end <- 3
step <- 1
fn$sqldf("
  WITH RECURSIVE generate_series(value) AS (
    SELECT $start
    UNION ALL
    SELECT value+$step FROM generate_series
     WHERE value+$step<=$end
) SELECT value FROM generate_series
")
##   value
## 1     1
## 2     2
## 3     3

2) 非递归 CTE 假设我们有一个已知至少具有所需行数的数据框。它的内容并不重要。例如,内置的 BOD 数据框有 6 行,假设我们想要 3 行,不超过 6 行,所以它可以工作。

fn$sqldf("
  WITH generate_series(value) AS (
    SELECT $start + $step * (rowid - 1) FROM BOD LIMIT ($end - $start) / $step + 1
  ) SELECT value FROM generate_series
")
##   value
## 1     1
## 2     2
## 3     3

如果 startstep 是 1 这可以简化为:

fn$sqldf("
  WITH generate_series(value) AS (
    SELECT rowid FROM BOD LIMIT $end
  ) SELECT value FROM generate_series
")

3) 在 R 中创建 另一种可能性是在 R 中创建系列,然后在 sqldf:

中使用它
generate_series <- data.frame(value = seq(start, end, step))
sqldf("SELECT value FROM generate_series")
##   value
## 1     1
## 2     2
## 3     3