PostgreSQL:连接函数结果表

PostgreSQL: Join function result table

提问人:ebbishop 提问时间:11/18/2023 更新时间:11/18/2023 访问量:45

问:

我有一张表格,上面有两点的纬度和液化天然气:

CREATE TABLE location_pairs (
  lat_1     float,
  lng_1     float,
  lat_2     float,
  lng_2     float
);

我还有一个函数,它接受两个纬度/液化格坐标对,并返回一个包含多个计算列(以米为单位的距离、以度为单位的距离等)的表。

简化功能:

CREATE OR REPLACE FUNCTION distances(lng_1 float, lat_1 float, lng_2 float, lat_2 float)
    RETURNS TABLE (
      distance_m float,
      distance_l float,
      distance_actual float,
      corrected_ratio float
    ) AS $$
    BEGIN
        RETURN QUERY
            ...
        ;
    END;
$$ LANGUAGE plpgsql;

我想编写一个查询,该查询将采用原始表并添加函数结果中的列:

 lat_1 | lng_1 | lat_2 | lng_2  | distance_m | etc
-------+-------+-------+--------+------------+-----
     0 |     0 |     1 |     1  |          x | ...

到目前为止,我所拥有的是:

SELECT
  *,
  distances(lng_1, lat_1, lng_2, lat_2)
FROM location_pairs;

这给出了结果

 lat_1 | lng_1 | lat_2 | lng_2  |         distances
-------+-------+-------+--------+-----------------------------
     0 |     0 |     1 |     1  | (x, y, other, results, ...)

如何将列拆分为函数生成的列?我假设我需要重新构建我的查询,但我不确定如何。distances

sql postgresql psql

评论


答:

1赞 Frank Heikens 11/18/2023 #1

像 FROM 中的表一样使用函数:

SELECT
      * -- use column names
FROM location_pairs
    , distances(lng_1, lat_1, lng_2, lat_2) d;
1赞 Krauss 11/18/2023 #2

您必须使用 .但首先,我建议你创建一个类型以避免来自服务器的投诉,并将返回声明为类型而不是表。FROM

CREATE TYPE distance_t AS (
    distance_m float,
    distance_l float,
    distance_actual float,
    corrected_ratio float
 );
    
CREATE OR REPLACE FUNCTION distances(lng_1 float, lat_1 float, lng_2 float, lat_2 float)
    RETURNS distance_t AS $$
DECLARE
    result distance_t;  -- We need to declare the return variable before using it
BEGIN
    SELECT-- your calculations here separated by commas;
    INTO result; -- the data will be stored in the variable
   
    RETURN result; -- return the variable
END;
$$ LANGUAGE plpgsql;
  
SELECT * FROM distances(1.0, 2.0, 3.0, 4.0);

如果需要加入输入

SELECT *
FROM location_pairs as loc,distances(loc.lat_1,  loc.lng_1, loc.lat_2,loc.lng_2 );