En el lenguaje de programación R, estoy interesado en realizar una "unión aproximada" y pasar esto a través de una conexión SQL:
library(fuzzyjoin) library(dplyr) library(RODBC) library(sqldf) con = odbcConnect("some name", uid = "some id", pwd = "abc") sample_query = sqlQuery( stringdist_inner_join(table_1, table_2, by = "id2", max_dist = 2) %>% filter(date_1 >= date_2, date_1 <= date_3) ) view(sample_query)Sin embargo, no creo que esto sea posible, porque la función que estamos utilizando para la "unión aproximada" (stringdist_inner_join) no es compatible con Netezza.
Traté de encontrar el código fuente para esta función de "unión difusa" y lo encontré aquí: https://rdrr.io/cran/fuzzyjoin/src/R/stringdist_join.R
Mi pregunta: ¿Alguien sabe si es posible (manualmente) convertir esta función de "unión aproximada" a un formato SQL que Netezza reconocerá? ¿Existen formas rápidas de volver a escribir esta función (stringdist_inner_join) para que Netezza pueda reconocerla? ¿Hay formas preexistentes de hacer esto?
En este momento, solo puedo ejecutar "sample_query" localmente: volver a escribir esta función (stringdist_inner_join) permitiría realizar "sample_query" mucho más rápido.
¿Alguien sabe si esto es posible?
Nota:
Mis datos se ven así:
table_1 = data.frame(id1 = c("123 A", "123BB", "12 5", "12--5"), id2 = c("11", "12", "14", "13"), date_1 = c("2010-01-31","2010-01-31", "2015-01-31", "2018-01-31" )) table_1$id1 = as.factor(table_1$id1) table_1$id2 = as.factor(table_1$id2) table_1$date_1 = as.factor(table_1$date_1) table_2 = data.frame(id1 = c("0123", "1233", "125 .", "125_"), id2 = c("111", "112", "14", "113"), date_2 = c("2009-01-31","2010-01-31", "2010-01-31", "2010-01-31" ), date_3 = c("2011-01-31","2010-01-31", "2020-01-31", "2020-01-31" )) table_2$id1 = as.factor(table_2$id1) table_2$id2 = as.factor(table_2$id2) table_2$date_2 = as.factor(table_2$date_2) table_2$date_3 = as.factor(table_2$date_3)Basado en su otra publicación sobre este problema, se resolvió una solución a la cuestión de cómo estructurar la consulta SQL:
select a.*, b.* from table_a a inner join table_b b on (a.date_1 between b.date_2 and b.date_3) and (le_dst(a.id1, b.id1) = 1 or a.id2 = b.id2) Para que esto se ejecute en un script R, recomendaría usar dbplyr y crearlo usando tbl para que pueda continuar con la manipulación básica como si fuera un data.frame y dbplyr lo traducirá a SQL (al menos comandos básicos) , luego combine todo en una consulta y, finalmente, extraiga los datos de la consulta con la función collect() .
Editar: solo una nota, el comando tbl comenzará a crear una declaración SQL y obtendrá los nombres de las columnas, pero no lo ejecutará para extraer datos hasta que ingrese collect() , momento en el que R enviará la consulta al servidor, el El servidor ejecutará la consulta y enviará los datos.
Solo tenga esto en cuenta porque si dbplyr no puede traducir algo a SQL, asumirá que es un comando SQL e intentará enviarlo, por lo que no sabrá que hay un error hasta que intente recopilar. Por ejemplo, una función del paquete stringr , str_dectect , no está implementada en dbplyr , por lo que dbplyr enviaría ese comando a la base de datos, lo que arrojaría un error porque no sabe qué es, pero solo después de ejecutar collect() . Consulte la página de dbplyr vinculada anteriormente para obtener más detalles.
library(dbplyr) new_con<- dbConnect( odbc(), Driver= "ODBC Driver 17 for SQL Server (as an example)", Server = "Server name here", uid = "some_id", pwd = "abc" ) sample_query<- dbplyr::tbl( new_con, dbplyr::sql( "select a.*, b.* from table_a a inner join table_b b on (a.date_1 between b.date_2 and b.date_3)" sample_data<-sample_query %>% filter(silly_example==TRUE) %>% collect()Estoy de acuerdo con el enfoque de @ Roger-123. Pero aquí hay una variación que podría ayudar:
Suponiendo que está utilizando conexiones remotas para acceder a la base de datos de Netezza, podría hacerlo utilizando dbplyr de la siguiente manera:
remote_1 = tbl(con, "table_1_name") remote_2 = tbl(con, "table_2_name") # create dummy column remote_1 = mutate(remote_1, ones = 1) remote_2 = mutate(remote_2, ones = 1) output = remote_1 %>% # cross_join inner_join(remote_2, by = "ones", prefix = c("_1","_2")) %>% # calculate Levenshtein distance mutate(distance = le_dst(id1, id2)) %>% # filter to close matches filter(distance <= 2)Notas:
inner_join si las condiciones son simples, o crear otra condición de filtro si son complejas.le_dst no es una función de R y no hay una traducción de dbplyr para ella, por lo que dbplyr la pasará al servidor tal como está.le_dst y dle_dst . Puedes usar lo que quieras aquí.Output es una consulta, actuará como una tabla pero se genera/calcula sobre la marcha. No se ha escrito en el disco ni se ha cargado en la memoria R. Dependiendo de su aplicación, querrá almacenar/guardar esto.