首页 > 解决方案 > 如何使用 R 将 data.frame 传递给 SQL“IN”条件?

问题描述

我正在从 R 中的 CSV 文件中读取值列表,并尝试将这些值传递给 SQL(dbGetQuery) 的 IN 条件。有人可以帮我解决这个问题吗?

library(rJava)
library(RJDBC)
library(dbplyr)
library(tibble)
library(DBI)
library(RODBC)
library(data.table)


jdbcDriver <- JDBC("oracle.jdbc.OracleDriver",classPath="C://Users/********/Oracle_JDBC/ojdbc6.jar")

jdbcConnection <- dbConnect(jdbcDriver, "jdbc:oracle:thin:Rahul@//Host/DB", "User_name", "Password") 

## Setting working directory for the data
setwd("C:\\Users\\**********\\Desktop")

## reading csv file into data frame
pii<-read.csv("sample.csv")

pii

 PII_ID
S0094-5765(17)31236-5
S0094-5765(17)31420-0
S0094-5765(17)31508-4
S0094-5765(17)31522-9
S0094-5765(17)30772-5
S0094-5765(17)30773-7

PII_ID1<-dbplyr::build_sql(pii$PII_ID)

PII_ID1

<SQL> ('S0094-5765(17)31236-5', 'S0094-5765(17)31420-0', 'S0094-5765(17)31508-4', 'S0094-5765(17)31522-9', 'S0094-5765(17)30772-5', 'S0094-5765(17)30773-7')


Data<-dbGetQuery(jdbcConnection, "SELECT ARTICLE_ID FROM JRBI_OWNER.JRBI_ARTICLE_DIM WHERE PII_ID in  ?",(PII_ID1))

预期的:

ARTICLE_ID
12345
23456
12356
14567
13456

实际结果:

[1] ARTICLE_ID
<0 rows> (or 0-length row.names)

标签: sqlrdbplyr

解决方案


您在第二个参数中传递的 SQL 代码dbGetQuery只是一个文本字符串,因此您可以使用paste或等效项来构造它。

您正在追求以下内容:

in_clause <- paste0("('", paste0(pii$PII_ID, collapse = "', '"), "')")

sql_text <- paste0("SELECT ARTICLE_ID 
              FROM JRBI_OWNER.JRBI_ARTICLE_DIM
              WHERE PII_ID IN ", in_clause)

 data <- dbGetQuery(jdbcConnection, sql_text)

但是,第一个的确切形式paste0取决于PII_ID(我假设它是文本)的格式以及这种格式在 sql 中的表示方式(我假设它是单引号)。

在将其传递sql_textdbGetQuery.

重要提示:此方法仅适用于pii包含少量值的情况(我建议少于 10 个)。如果pii包含大量值,您的查询将非常大并且运行速度非常慢。如果您有很多值,pii那么根据@nicola 的评论,更好的方法是加入或半加入。


推荐阅读