首页 > 解决方案 > For循环在R中迭代SQL查询

问题描述

我想在我的 df 中的 17 行上迭代这个 SQL 查询。我的df和代码如下。我想我可能需要在 dat$ptt_id 周围加上单引号,因为在“IN”函数中出现语法错误。任何想法如何正确写这个?

df 看起来像:

   ptt_id
1  181787
2  181788
3  184073
4  184098
5  197601
6  197602
7  197603
8  197604
9  197605
10 197606
11 197607
12 197608
13 197609
14 200853
15 200854
16 200851
17 200852

#加载数据----

dat <- read.csv("ptts.csv")
dat2<-list(dat)

#发送到数据库----

for(i in 1:nrow(dat)){

  q <- paste("SELECT orgnl_pit, t_name, cap_date, species, sex, mass, cap_lat, cap_lon, sat_appld_id
      FROM main.capev JOIN uid.turtles USING (orgnl_pit)
        WHERE sat_appld_id IN", dat$ptt_id[i],";")
  
  #Get query----
  tags <- dbGetQuery(conn, q)

}

Error in postgresqlExecStatement(conn, statement, ...) : 
  RS-DBI driver: (could not Retrieve the result : ERROR:  syntax error at or near "181787"
LINE 3:         WHERE sat_appld_id IN 181787 ;
                                      ^

感谢您的任何帮助。

标签: sqlrfor-looppaste

解决方案


两种选择:

  1. 参数绑定。

    qmarks <- paste0("(", paste(rep("?", nrow(df)), collapse = ","), ")")
    qmarks
    # [1] "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
    qry <- paste(
      "SELECT orgnl_pit, t_name, cap_date, species, sex, mass, cap_lat, cap_lon, sat_appld_id
       FROM main.capev JOIN uid.turtles USING (orgnl_pit)
       WHERE sat_appld_id IN", qmarks)
    tags <- dbGetQuery(conn, qry, params = df[,1])
    
  2. 临时表。当您要使用大量 id 时,这可能会更有用。(如果您仍然从数据库中获取 id,这也可以在没有临时表的情况下工作,并且可以在此子查询中使用该查询。)

    dbWriteTable(conn, df, "mytemp")
    qry <- "SELECT orgnl_pit, t_name, cap_date, species, sex, mass, cap_lat, cap_lon, sat_appld_id
            FROM main.capev JOIN uid.turtles USING (orgnl_pit)
            WHERE sat_appld_id IN (select id from mytemp)"
    tags <- dbGetQuery(conn, qry)
    dbExecute(conn, "drop table mytemp")
    

    (仔细命名您的临时表。DBMS 通常有一个命名法,以确保在您断开连接时自动清理/删除该表,通常类似于"#mytemp"。请咨询您的 DBMS 或 DBA。)


推荐阅读