【问题标题】:PL/R function accepting two tables as argumentsPL/R 函数接受两个表作为参数
【发布时间】:2016-03-19 15:56:05
【问题描述】:

我正在努力寻找可以接受两个 postgres 表的 PL/R 函数的示例。 PL/R docs 没有提供任何此类示例。
为了有一个工作示例,让我们考虑在 R 端使用两个 postgres 表的合并。

在 postgres 中有两个表

CREATE TABLE x (a numeric, b text);
CREATE TABLE y (a numeric, d text);
INSERT INTO x VALUES (1, 'a'),(2, 'b');
INSERT INTO y VALUES (2, 'b'),(3, 'c');

我正在寻找替换以下查询

SELECT * FROM x INNER JOIN y ON x.a=y.a;

在 R 中定义的 PL/R 函数为:

my_function = function(x, y){
    merge(x, y, by = "a")
}

我能够调用 PL/R 函数,它接受单个表,但不是两个。

【问题讨论】:

  • 这在 (postgres) SQL 中并非不可能,您只需要动态 SQL:生成一个使用表名和列名的 SQL 查询,并执行此查询,返回结果行。 (by= "a" 的参数传递形式可能需要稍微改变一下)

标签: r postgresql plpgsql plr


【解决方案1】:

我不认为 postgeql 可以接受真实表格作为参数。

但是还有另一种方法可以做到这一点。您可以将表名作为参数传递。
这是函数

CREATE OR REPLACE FUNCTION merge(t1 text, t2 text)
returns setof x as 
   BEGIN
     execute 'select * from ' || t1 ||' join ' || t2 || ' on t1.a=t2.a';
   END

以上是postgresql的函数,也可以写成R函数。
这是R的代码

  1. 我们必须将表 x 的所有值存储到变量 x 中。请参阅下面的代码

    x <- dbGetQuery(con, "SELECT * from sandbox.x") --con 是连接到你的数据库的连接,sandbox 是模式名,x 是表名

  2. 将表 y 的值存储到变量 y 中

    y<-dbGetQuery(con, "SELECT * from sandbox.y")

  3. 合并两张表

    total <- merge(x,y,by="a")

  4. 你也可以写另一个函数来包装合并函数,见下面的代码

    myTotal <- function(x,y) { result <- merge(x,y,by="a") return(result) }

我附上了步骤截图供你参考

【讨论】:

  • R 代码中确实有合并两个表的功能。首先,您必须创建 2 个数据框(数据集),这些数据框应与表的定义相匹配。然后你可以使用内置函数merge,见下面的代码total
  • 我已经更新了我的答案,你可以看看。如果您有任何问题,请告诉我
  • @Robinson 我想出了同样的答案。你打败了我。有一些用于连接到 postgres 的包,例如 RPostgreSQL。 PL/R 似乎不太支持其他操作系统。我一生都无法理解为什么一个表的名称是不够的,因为 Sql 是作为文本执行的。作为旁注“MERGE 不在 9.4.5 中(截至 2015 年 10 月 8 日的最新 PostgreSQL 版本)UPSERT 功能将在 PostgreSQL 9.5 版本中 - 请参阅 PostgreSQL 9.5 中的新增功能” Ref wiki.postgresql.org/wiki/SQL_MERGE
  • @pnorton 当我在帖子中引用表时,我指的是表对象(包含表定义,包括主键、约束和数据)而不是表名。更清楚地说,jangorecki 想要在 R 端而不是 postgresql 中进行连接。有可能的。我已经更新了 R 端的代码。
  • 天哪,我已经是 RPostgreSQL 高级用户了。我已经问过希望得到准确答案的问题。 @pnorton 我已经在 R 包 pg 中使用 RPostgreSQL 合并了 UPSERT,并在后台使用临时表。
猜你喜欢
  • 2015-03-24
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 2011-09-13
  • 1970-01-01
相关资源
最近更新 更多