Postgres 中的参数化查询并将结果附加到新数据框中
Parametrize query in RPostgres and append results in a new dataframe
我有一组存储在数据框中的对值 parameters
:
parameters <- data.frame(
variant_id = c(1, 2, 3, 4, 5),
start_date = c("2019-07-01", "2019-09-05", "2019-05-21", "2019-09-06",
"2019-04-19"))
> parameters
variant_id start_date
1 1 2019-07-01
2 2 2019-09-05
3 3 2019-05-21
4 4 2019-09-06
5 5 2019-04-19
我想在 RPostgres 中执行的 SQL 查询中使用 variant_id
和 start_date
的这种组合作为动态参数。
library(RPostgres)
library(tidyverse)
query <- "select sum(o.quantity)
from orders o
where o.date >= << start_date >>
and o.variant_id = << variant_id >> "
df <- dbGetQuery(db, query)
然后我会有这样的查询:
query_1 <- "select sum(o.quantity)
from orders o
where o.date >= '2019-07-01'
and o.variant_id = 1 "
result_1 <- dbGetQuery(db, query_1)
> result_1
sum
1 100
query_2 <- "select sum(o.quantity)
from orders o
where o.date >= '2019-09-05'
and o.variant_id = 2 "
result_2 <- dbGetQuery(db, query_2)
> result_2
sum
1 120
query_3 <- "select sum(o.quantity)
from orders o
where o.date >= '2019-05-21'
and o.variant_id = 3 "
result_3 <- dbGetQuery(db, query_3)
> result_3
sum
1 140
...等等。
然后,我想将每个结果附加到一个新的数据框中 results
为:
results <- data.frame(
variant_id = c(1, 2, 3, 4, 5),
quantity = c(100, 120, 140, 150, 160)
)
> results
variant_id quantity
1 1 100
2 2 120
3 3 140
4 4 150
5 5 160
如何使用 RPostgres
和 dplyr
避免使用循环来解决这个问题?
我们没有您的数据库,但使用了最后注释中给出的 parameters
和 orders
。我们在 parameters
定义中添加了 stringsAsFactors = FALSE
以确保我们有字符串。
现在,使用 sprintf
创建查询的字符向量。然后 运行 每一个。这里我们使用 sqldf
使所有内容都可重现,因为我们没有您的数据库,但您可以将 sqldf
替换为适当的语句以从您的数据库中获取结果。
query <- "select sum(o.quantity)
from orders o
where o.date >= '%s'
and o.variant_id = %s "
queries <- with(parameters, sprintf(query, start_date, variant_id))
library(sqldf)
# replace sqldf in next line with appropriate function to invoke query
do.call("rbind", lapply(queries, sqldf))
## sum(o.quantity)
## 1 1
## 2 NA
## 3 3
## 4 NA
## 5 NA
备注
# test data
parameters <- data.frame(
variant_id = c(1, 2, 3, 4, 5),
start_date = c("2019-07-01", "2019-09-05", "2019-05-21", "2019-09-06",
"2019-04-19"), stringsAsFactors = FALSE)
orders <- data.frame(date = "2019-07-02", variant_id = 1:3, quantity = 1:3)
我有一组存储在数据框中的对值 parameters
:
parameters <- data.frame(
variant_id = c(1, 2, 3, 4, 5),
start_date = c("2019-07-01", "2019-09-05", "2019-05-21", "2019-09-06",
"2019-04-19"))
> parameters
variant_id start_date
1 1 2019-07-01
2 2 2019-09-05
3 3 2019-05-21
4 4 2019-09-06
5 5 2019-04-19
我想在 RPostgres 中执行的 SQL 查询中使用 variant_id
和 start_date
的这种组合作为动态参数。
library(RPostgres)
library(tidyverse)
query <- "select sum(o.quantity)
from orders o
where o.date >= << start_date >>
and o.variant_id = << variant_id >> "
df <- dbGetQuery(db, query)
然后我会有这样的查询:
query_1 <- "select sum(o.quantity)
from orders o
where o.date >= '2019-07-01'
and o.variant_id = 1 "
result_1 <- dbGetQuery(db, query_1)
> result_1
sum
1 100
query_2 <- "select sum(o.quantity)
from orders o
where o.date >= '2019-09-05'
and o.variant_id = 2 "
result_2 <- dbGetQuery(db, query_2)
> result_2
sum
1 120
query_3 <- "select sum(o.quantity)
from orders o
where o.date >= '2019-05-21'
and o.variant_id = 3 "
result_3 <- dbGetQuery(db, query_3)
> result_3
sum
1 140
...等等。
然后,我想将每个结果附加到一个新的数据框中 results
为:
results <- data.frame(
variant_id = c(1, 2, 3, 4, 5),
quantity = c(100, 120, 140, 150, 160)
)
> results
variant_id quantity
1 1 100
2 2 120
3 3 140
4 4 150
5 5 160
如何使用 RPostgres
和 dplyr
避免使用循环来解决这个问题?
我们没有您的数据库,但使用了最后注释中给出的 parameters
和 orders
。我们在 parameters
定义中添加了 stringsAsFactors = FALSE
以确保我们有字符串。
现在,使用 sprintf
创建查询的字符向量。然后 运行 每一个。这里我们使用 sqldf
使所有内容都可重现,因为我们没有您的数据库,但您可以将 sqldf
替换为适当的语句以从您的数据库中获取结果。
query <- "select sum(o.quantity)
from orders o
where o.date >= '%s'
and o.variant_id = %s "
queries <- with(parameters, sprintf(query, start_date, variant_id))
library(sqldf)
# replace sqldf in next line with appropriate function to invoke query
do.call("rbind", lapply(queries, sqldf))
## sum(o.quantity)
## 1 1
## 2 NA
## 3 3
## 4 NA
## 5 NA
备注
# test data
parameters <- data.frame(
variant_id = c(1, 2, 3, 4, 5),
start_date = c("2019-07-01", "2019-09-05", "2019-05-21", "2019-09-06",
"2019-04-19"), stringsAsFactors = FALSE)
orders <- data.frame(date = "2019-07-02", variant_id = 1:3, quantity = 1:3)