首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用glue_sql()并避免在动态SELECT语句中粘贴?

如何使用glue_sql()并避免在动态SELECT语句中粘贴?
EN

Stack Overflow用户
提问于 2021-08-13 22:07:40
回答 2查看 595关注 0票数 2

我正在学习如何从R中查询SQLite数据库,并使用glue_sql()构建这些查询。下面是我的工作流程中子查询的一个简化示例。有没有一种方法可以不使用s10_wtXs20_wtX来创建paste0(),如下面的代码所示?

代码语言:javascript
复制
library(DBI)
library(dplyr)
library(glue)

# example database
set.seed(1)
ps <- data.frame(plot = rep(1:3, each = 4),
                 spp = rep(1:3*10, 2),
                 wtX = rnorm(12, 10, 2) %>% round(1))
con <- dbConnect(RSQLite::SQLite(), "")
dbWriteTable(con, "ps", ps)

# species of interest
our_spp <- c(10, 20)

# for the spp of interest, sum wtX on each plot
sq <- glue_sql(paste0(
  'SELECT ps.plot,\n',
  paste0('SUM(CASE WHEN ps.spp = ', our_spp,
         ' THEN (ps.wtX) END) AS s', our_spp,
         '_wtX',
         collapse = ',\n'), '\n',
  '  FROM ps
    WHERE ps.spp IN ({our_spp*}) -- spp in our sample
    GROUP BY ps.plot'),
  .con = con)

# the result of the query should look like:
dbGetQuery(con, sq)
  plot s10_wtX s20_wtX
1    1    21.9    10.4
2    2    11.0    22.2
3    3     9.4    13.0

在我的实际工作流程中,我有两种以上的兴趣,所以我宁愿不完全写出每一行(例如,SUM(CASE WHEN ps.spp = 10 THEN (ps.wtX) END) AS s10_wtX)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-13 22:58:49

OP最初的问题是

是否有一种无需使用paste0()就可以创建s10_wtX和s20_wtX的方法,如下面的代码所示?

如果我们只想用glue进行构造,也可以使用glue_collapse

代码语言:javascript
复制
library(glue)
sq1 <- glue_sql('SELECT ps.plot,', glue_collapse(glue('SUM(CASE WHEN ps.spp = {our_spp} THEN (ps.wtX) END) AS s{our_spp}_wtX'), sep = ",\n"), '\nFROM ps\n WHERE ps.spp IN ({our_spp*}) -- spp in our sample\n    GROUP BY ps.plot', .con = con)
dbGetQuery(con, sq1)
  plot s10_wtX s20_wtX
1    1    21.9    10.4
2    2    11.0    22.2
3    3     9.4    13.0
票数 2
EN

Stack Overflow用户

发布于 2021-08-13 22:35:31

为了正式化这一点(即使这不是您最终使用的),下面是我的详细评论:

代码语言:javascript
复制
out <- DBI::dbGetQuery(con, "
  select ps.plot, ps.spp, sum(ps.wtX) as wtX
  from ps
  where ps.spp in (10,20)
  group by ps.plot, ps.spp")
out
#   plot spp  wtX
# 1    1  10 21.9
# 2    1  20 10.4
# 3    2  10 11.0
# 4    2  20 22.2
# 5    3  10  9.4
# 6    3  20 13.0

这可以很容易地转到你需要的地方。例如,使用tidyr::pivot_wider

代码语言:javascript
复制
tidyr::pivot_wider(out, plot, names_from="spp", values_from="wtX")
# # A tibble: 3 x 3
#    plot  `10`  `20`
#   <int> <dbl> <dbl>
# 1     1  21.9  10.4
# 2     2  11    22.2
# 3     3   9.4  13  

(名字需要清理。)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68778804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档