#PGR_DRIVINGDISTANCE

pgr_drivingdistance
PGR_DRIVINGDISTANCE ( EdgesSQL , RootVid , distance , directed )
pgr_drivingdistance
PGR_DRIVINGDISTANCE ( EdgesSQL , RootVid , distance , directed , equicost )

PGR_DRIVINGDISTANCE函数基于Dijkstra算法计算从一个或多个起始点出发在给定距离限制内能够到达的所有终点或区域。

本函数作为表函数使用,返回包含以下列的表:

列名 数据类型 描述
SEQ INTEGER 路径的序号,是从1开始的顺序值
FROM_V BIGINT 起始点的标识ID,仅equicost为TRUE时存在该列
NODE BIGINT 从起始点出发的指定距离(distance参数)内的终点标识符
EDGE BIGINT 到达该终点(NODE列)所用的边的标识符
值为0表示起始点=终点
COST DOUBLE 起始点-终点的边成本
AGG_COST DOUBLE 起始点-终点的总开销

EdgesSQL

查询图形数据的SQL语句,其值须为VARCHAR类型以及能够转换成VARCHAR的类型。

  • EdgeSQL执行后所有投影列总大小不能超过63K。

  • EdgesSQL需获取以下信息:

    列名 支持的数据类型 描述
    id TINYINT、SMALLINT、INT或BIGINT 边的标识符
    source TINYINT、SMALLINT、INT或BIGINT 边的第一个端点顶点的标识符
    target TINYINT、SMALLINT、INT或BIGINT 边的第二个端点顶点的标识符
    cost TINYINT、SMALLINT、INT、BIGINT、FLOAT、DOUBLE或NUMBER 从source到target的权重
    reverse_cost TINYINT、SMALLINT、INT、BIGINT、FLOAT、DOUBLE或NUMBER 从target到source的权重,默认值为-1
    当reverse_cost为负数时表示从target到source不可达
  • 当EdgesSQL为NULL时,函数返回NUL。

RootVid

起始点的标识符,其值须为BIGINT类型以及能够转换成BIGINT的类型。

当rootVid为NULL时,函数返回NULL。

RootVids

起始点的标识数组,其值须为由BIGINT类型构成的ARRAY类型。

  • 如果数组中存在为NULL的元素,函数将报错。

  • 当rootVids为NULL时,函数返回NULL。

distance

距离限制,其值为DOUBLE类型以及能够转换成DOUBLE的类型。

当distance为NULL时,函数返回NULL。

directed

指定EdgesSQL查询的图是否为有向图,其值为BOOLEAN类型以及能够转换成BOOLEAN的类型。

默认值为TRUE(有向图),若设置为FALSE则表示EdgesSQL查询的图为无向图。

equicost

指定是否仅保留距离最短的路径数据,其值须为BOOLEAN类型以及能够转换成BOOLEAN的类型。

默认值为 FALSE(不清理数据),若设置为TRUE要求输入边表必须包含多个起始顶点,且仅保留距离最短的路径相关数据。

示例(HEAP表)

SELECT * FROM pgr_drivingDistance('SELECT id, source, target, cost, reverse_cost FROM edges',1, 5.1);

                  SEQ                  NODE                  EDGE        COST    AGG_COST
--------------------- --------------------- --------------------- ----------- -----------
                    1                     1                    -1           0           0
                    2                     2                     1    1.0E+000    1.0E+000
                    3                     5                     4    1.2E+000    1.2E+000
                    4                     6                     5    8.0E-001    2.0E+000
                    5                     3                     2    1.5E+000    2.5E+000
                    6                     4                     6    1.7E+000    3.7E+000
                    
SELECT * FROM pgr_drivingDistance('SELECT id, source, target, cost, reverse_cost FROM edges',ARRAY(1, 2), 5.1, false, false);

                  SEQ                FROM_V                  NODE                  EDGE        COST    AGG_COST
--------------------- --------------------- --------------------- --------------------- ----------- -----------
                    1                     1                     1                    -1           0           0
                    2                     1                     2                     1    1.0E+000    1.0E+000
                    3                     1                     5                     4    1.2E+000    1.2E+000
                    4                     1                     6                     5    8.0E-001    2.0E+000
                    5                     1                     3                     2    1.5E+000    2.5E+000
                    6                     1                     4                     6    1.7E+000    3.7E+000
                    7                     2                     2                    -1           0           0
                    8                     2                     1                     1    1.0E+000    1.0E+000
                    9                     2                     3                     2    1.5E+000    1.5E+000
                   10                     2                     5                     4    1.2E+000    2.2E+000
                   11                     2                     6                     5    8.0E-001    3.0E+000
                   12                     2                     4                     3    2.0E+000    3.5E+000

SELECT * FROM pgr_drivingDistance('SELECT id, source, target, cost, reverse_cost FROM edges',ARRAY(1, 2), 5.1, false, true);

                  SEQ                FROM_V                  NODE                  EDGE        COST    AGG_COST
--------------------- --------------------- --------------------- --------------------- ----------- -----------
                    1                     1                     1                    -1           0           0
                    2                     1                     5                     4    1.2E+000    1.2E+000
                    3                     1                     6                     5    8.0E-001    2.0E+000
                    4                     2                     2                    -1           0           0
                    5                     2                     3                     2    1.5E+000    1.5E+000
                    6                     2                     4                     3    2.0E+000    3.5E+000



-- 本函数不支持绑定参数,报错YAS-07204 no function matches the given name and argument types
SET serveroutput ON;
DROP TABLE IF EXISTS   main_edges_ydbrd3621_84;
CREATE TABLE main_edges_ydbrd3621_84 (
    id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    source INT NOT NULL,
    target INT NOT NULL,
    cost INT NOT NULL,
    reverse_cost INT,
    category_id INT,
    region_id INT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建分类表
DROP TABLE IF EXISTS   categories_ydbrd3621_84;
CREATE TABLE categories_ydbrd3621_84 (
    id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    priority INT DEFAULT 1,
    is_active INT DEFAULT 1
);
-- 创建区域表
DROP TABLE IF EXISTS   regions_ydbrd3621_84;
CREATE TABLE regions_ydbrd3621_84 (
    id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    population INT,
    area_code VARCHAR(10)
);
-- 插入基础数据
INSERT INTO categories_ydbrd3621_84 (name, priority, is_active) VALUES ('highway', 3, 1);
INSERT INTO categories_ydbrd3621_84 (name, priority, is_active) VALUES ('avenue', 2, 1);
INSERT INTO categories_ydbrd3621_84 (name, priority, is_active) VALUES ('street', 1, 1);
INSERT INTO categories_ydbrd3621_84 (name, priority, is_active) VALUES ('disabled', 0, 0);
INSERT INTO regions_ydbrd3621_84 (name, population, area_code) VALUES ('downtown', 50000, 'DT');
INSERT INTO regions_ydbrd3621_84 (name, population, area_code) VALUES ('suburban', 30000, 'SB');
INSERT INTO regions_ydbrd3621_84 (name, population, area_code) VALUES ('industrial', 20000, 'ID');
INSERT INTO main_edges_ydbrd3621_84 (source, target, cost, reverse_cost, category_id, region_id) VALUES
(1, 2, 1.0, 1.0, 1, 1),
(2, 3, 1.5, 1.5, 1, 1),
(3, 4, 2.0, 2.0, 1, 1),
(1, 5, 3.0, 3.0, 2, 2),
(5, 6, 1.2, 1.2, 2, 2),
(6, 4, 1.8, 1.8, 2, 2),
(2, 7, 2.5, 2.5, 3, 3),
(7, 8, 1.3, 1.3, 3, 3),
(8, 4, 2.2, 2.2, 3, 3);
COMMIT;

DECLARE
    v_edges_sql VARCHAR2(1000) := 'SELECT id, source, target, cost FROM main_edges_ydbrd3621_84 WHERE cost <= :max_cost';
    v_max_cost NUMBER := 3.0;
    v_start_node NUMBER := 1;
    v_distance NUMBER := 4.0;
    v_directed BOOLEAN := TRUE;
    v_result_count NUMBER;
BEGIN
    DBMS_OUTPUT.PUT_LINE('=== pgr_drivingDistance comprehensive scenario bound parameter testing ===');
    -- 构建动态SQL字符串(避免绑定变量在SQL字符串中的问题)
    DECLARE
        v_dynamic_edges_sql VARCHAR2(1000);
    BEGIN
        -- 构建包含具体值的SQL字符串
        v_dynamic_edges_sql := 'SELECT id, source, target, cost FROM main_edges_ydbrd3621_84 WHERE cost <= ' || v_max_cost;
        
        DBMS_OUTPUT.PUT_LINE('Used edge query SQL: ' || v_dynamic_edges_sql);
        DBMS_OUTPUT.PUT_LINE('Starting point: ' || v_start_node || ', Distance Limit: ' || v_distance ||
                           ', Directed: ' || CASE WHEN v_directed THEN 'Yes' ELSE 'No' END);
        
        -- 计算可达节点数量
        EXECUTE IMMEDIATE '
            SELECT COUNT(*) FROM pgr_drivingDistance(:edges_sql, :start_vid, :distance, :directed_flag)'
        INTO v_result_count
        USING v_dynamic_edges_sql, v_start_node, v_distance, v_directed;
        
        DBMS_OUTPUT.PUT_LINE('Comprehensive test for reachable node count:' || v_result_count);
        -- 如果有可达节点,显示详细结果
        IF v_result_count > 0 THEN
            DBMS_OUTPUT.PUT_LINE('Details of reachable nodes:');
            
            DECLARE
                v_sql VARCHAR2(2000);
                v_directed_str VARCHAR2(10);
            BEGIN
                -- 构建执行SQL
                IF v_directed THEN
                    v_directed_str := 'TRUE';
                ELSE
                    v_directed_str := 'FALSE';
                END IF;
                
                v_sql := 'SELECT seq, node, edge, cost, agg_cost FROM pgr_drivingDistance(''' ||
                         v_dynamic_edges_sql || ''', ' || v_start_node || ', ' || v_distance ||
                         ', ' || v_directed_str || ')';
                
                EXECUTE IMMEDIATE '
                    DECLARE
                        CURSOR c_result IS ' || v_sql || ';
                        v_rec c_result%ROWTYPE;
                    BEGIN
                        OPEN c_result;
                        LOOP
                            FETCH c_result INTO v_rec;
                            EXIT WHEN c_result%NOTFOUND;
                            DBMS_OUTPUT.PUT_LINE(''  seq:'' || v_rec.seq || 
                                               '', node:'' || v_rec.node || '', edge:'' || v_rec.edge ||
                                               '', cost:'' || v_rec.cost || '', agg_cost:'' || v_rec.agg_cost);
                        END LOOP;
                        CLOSE c_result;
                    END;';
            END;
        ELSE
            DBMS_OUTPUT.PUT_LINE('No reachable nodes found under the given conditions');
        END IF;
        
    EXCEPTION
        WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE('Comprehensive test execution failed: ' || SQLERRM);
            DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
    END;
END;
/

Execution results: YAS-07204 no function matches the given name and argument types


pdf-btn 下载文档 copy-btn 复制链接
edit-icon
反馈
coperate-icon
coperate
合作
communication-icon
communicate
交流