【问题标题】:preventing insert on duplicate values Postgres防止插入重复值Postgres
【发布时间】:2021-05-20 07:44:52
【问题描述】:

我正在用这个 SQL 语句构建一个距离矩阵:

INSERT INTO tabel (start, end, agg_cost)

SELECT * FROM pgr_dijkstraCostMatrix(
    'SELECT id, source, target, cost, reverse_cost FROM edges',
    (SELECT array_agg(id) FROM vertices 
     WHERE (vertices.eout =1)  OR (vertices.eout >15) ) 
);

效果很好。

当“开始”和“结束”的组合已存在于表中时,如何防止插入? 我正在寻找另一个 WHERE 子句,但找不到放在哪里。

【问题讨论】:

标签: sql postgresql distance-matrix


【解决方案1】:

如果UPSERT 不是一个选项,您可以尝试将此条件包含在SELECT 中,例如

INSERT INTO tabel (start, end, agg_cost)
SELECT * FROM pgr_dijkstraCostMatrix(
    'SELECT id, source, target, cost, reverse_cost FROM edges',
    (SELECT array_agg(id) FROM vertices 
     WHERE (vertices.eout =1)  OR (vertices.eout >15) ) 
) q WHERE NOT EXISTS (
            SELECT 1 FROM tabel t 
            WHERE t.start = q.start AND
                  t.end = q.end);

演示:db<>fiddle

【讨论】:

    【解决方案2】:

    当'start'和'end'的组合已经存在于表中时,如何防止INSERT?

    首先创建一个唯一索引或约束,然后使用on conflict:

    create unique index unq_tabel_start_end on tabel(start_end);
    
    INSERT INTO tabel (start, end, agg_cost)
        SELECT *
        FROM pgr_dijkstraCostMatrix(
                 'SELECT id, source, target, cost, reverse_cost FROM edges',
                 (SELECT array_agg(id)
                  FROM vertices 
                  WHERE vertices.eout = 1 OR vertices.eout > 15
                 )
                                  ) 
        ON CONFLICT (start, end) DO NOTHING;
    

    您也可以根据需要更新现有行,而不是忽略新数据。

    【讨论】:

    • @Maas 。 . .这是更好的解决方案,因为它使用数据库来确保唯一性。
    猜你喜欢
    • 1970-01-01
    • 2021-11-26
    • 2015-08-07
    • 1970-01-01
    • 2016-02-19
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多