Postgres如何创建一个在查询中使用的函数

Posted

技术标签:

【中文标题】Postgres如何创建一个在查询中使用的函数【英文标题】:Postgres how can I create a function to use inside a query 【发布时间】:2016-02-04 18:08:55 【问题描述】:

我对 postgres 比较陌生,并且正在使用 9.4 版本。我在 Java 中有一个简单的函数,有人告诉我如果让 postgres 来做它会更有效率。我的函数需要一个整数和一个来自数据库的字符串数据并转换它们。这是我的函数:注意它需要一个整数和一个字符串

private static String difference(Integer i,String created_on) 
    String id = "";
    if (i < 60) 
      ...
        
        else if (i >= 60 && i < 1440) 

       ....
     
else if (i >= 1440 && i < 10080) 

      ....

     
    else 

      ....
    

    return id;

这是我的查询,现在 Created_on 是字符串,last_reply 是整数

"SELECT created_on as created_on,
last_reply as last_reply;

一旦数据来自数据库,我将其放入循环中并通过以下方式对其进行转换:

  for(i=0;i<10;i++) 
      
                jo = new JSONObject();
                jo.put("last_reply", difference(rs.getInt("last_reply",
                                    rs.getString("created_on"))));
            

如您所见,数据转换发生在此处

差异(rs.getInt("last_reply", rs.getString("created_on")

我现在的问题是如何复制该函数并将其保存在 postgres 中,以便我可以进行这样的查询

**

**"SELECT difference(last_reply,created_on) as newvalue, created_on as created_on,
    last_reply as last_reply;**

** 据我所知,从性能的角度来看,最好让数据库执行此操作,而不是使用 Java 循环遍历数据。任何建议都会很棒...

更新

该功能用于社交应用程序,以分钟为单位测量发布内容的时间。如果小于 60 分钟,则返回“6 分钟前等”,如果介于 60-1440 之间,则返回“4 小时前等”。 .我已经完成了 If-else 语句中的计算,但没有包含它,以便代码看起来更美观。

这是完整的方法

private static String difference(Integer i,String created_on) 
    String id = "";
    if (i < 60) 

        if(i<1)
            id = "Now";

        else
            id = i + " min";
        
        else if (i >= 60 && i < 1440) 

        i=(i/60);
        if(i==0)
        i=1;
        id = i + " hrs";
     else if (i >= 1440 && i < 10080) 

        i=(i/1440);
        id = i + " day(s)";

    
    else 
  // Posted longer than 7 days so Created_On will show date created
 // Passed down to the id String
        id = created_on;

    

    return id;

【问题讨论】:

你的difference()方法的逻辑是什么?您只是展示了很多无意义的 if 子句,并且在任何地方都没有使用 String 参数。 它以分钟为单位测量时间,小于 60 是从 60 到 1440 的分钟返回小时加上数字。我会更新的。 String created_on 有什么作用?如果您不在任何地方使用它,为什么要将它作为参数传递?您的问题中有很多文字,但信息很少。 created_on 用在最后一个 else 块中。如果某些内容的发布时间超过 7 天,则 Created_on 会获取某些内容的创建日期,例如 1-20-2016 。我将在上面发布完整的方法代码。 我会先清理逻辑。您首先检查if(i &lt; 60)然后您重新检查if(i &lt; 1)(即如果i == 0)。你还在第二次对i==0 进行冗余检查,因为i 至少是60,所以它永远不会发生。然后我不会创建存储过程,而是使用CASE -THEN 【参考方案1】:

不确定 Java 差异函数的数据类型是什么,但您可以使用以下两种方法之一。将数据集从 Postgres 拉入 Java,然后通过将两个值传递给您的函数来找出其中的差异,然后将该结果集用于任何目的。

另一种方法是直接在 Postgres 中创建一个函数,然后从您的查询中调用该函数。

创建函数:

CREATE FUNCTION intDifference(integer, integer) RETURNS integer
    AS 'select $2 - $1;'
    LANGUAGE SQL
    IMMUTABLE
    RETURNS NULL ON NULL INPUT;

在查询中使用函数:

SELECT intDifference(last_reply,created_on) as newvalue, created_on as created_on, last_reply as last_reply
FROM SOME_TABLE;

【讨论】:

以上是关于Postgres如何创建一个在查询中使用的函数的主要内容,如果未能解决你的问题,请参考以下文章

使用 Postgres 函数作为 ActiveRecord 模型

Postgres: 如何在psql查询的字符串中插入双引号?

Postgres 在查询中使用函数

带有 jsonb 参数的 Postgres 函数

如何在不创建函数的情况下运行 plpgsql?

如何在 Postgres 函数中检索多个结果行?