簡體   English   中英

PostgreSQL 9.6中窗口功能中的不穩定查詢行為

[英]Unstable query behavior in windowing function in PostgreSQL 9.6

我從geofabrik.de下載了我所在國家/地區的OSM數據,並將其成功導入到Ubuntu 16.04上安裝的PostgreSQL 9.6,並多次使用。 我還創建了可正常運行的Web應用程序。 因此,我決定添加另一個功能,該功能可以從某些點返回最接近的特殊點(例如餐館)。 對於最近的一點,它可以工作,但是當我想要返回它們的數組時,它不起作用。 所以我分解了問題,發現了奇怪的行為。 當我執行以下查詢時:

SELECT t.osm_id
      FROM (
        SELECT DISTINCT ON (a.points) a.points, v.osm_id AS osm_id, MIN(ST_DISTANCE(v.the_geom, a.points)) OVER (PARTITION BY a.points ORDER BY ST_DISTANCE(v.the_geom, a.points))
        FROM (SELECT ST_GEOMFROMEWKT('SRID=4326;POINT(17.104854583740238 48.15099866770469)') AS points) a
        CROSS JOIN ways_vertices_pgr v
      ) AS t

它返回:

| osm_id            |
| ----------------- |
| 2338524511        |

當我在地圖上顯示此點時,它的位置離原始點很遠,並且在子查詢中更改了點后,結果仍然相同。 我也知道在顯示點和原始點之間有很多點,應該通過查詢返回。 然后我嘗試運行以下查詢:

SELECT t.*, t.osm_id
      FROM (
        SELECT DISTINCT ON (a.points) a.points, v.osm_id AS osm_id, MIN(ST_DISTANCE(v.the_geom, a.points)) OVER (PARTITION BY a.points ORDER BY ST_DISTANCE(v.the_geom, a.points))
        FROM (SELECT ST_GEOMFROMEWKT('SRID=4326;POINT(17.104854583740238 48.15099866770469)') AS points) a
        CROSS JOIN ways_vertices_pgr v
      ) AS t

它返回:

| points                                             | osm_id   | min                  | osm_id     |
| -------------------------------------------------- | -------- | -------------------- | --------   |
| 0101000020E6100000010000C0D71A3140FFC3A1EC53134840 | 33169309 | 0.000124886435658481 | 33169309   |

除了SELECT部分​​之外的整個查詢保持不變,但是結果不同,現在是正確的。 誰能建議我如何更改查詢以使其正常工作?

當您使用distinct on ,需要按order by 我認為這是您想要的第一個查詢邏輯:

    SELECT DISTINCT ON (a.points) a.points, v.osm_id AS osm_id,ST_DISTANCE(v.the_geom, a.points) as dist
    FROM (SELECT ST_GEOMFROMEWKT('SRID=4326;POINT(17.104854583740238 48.15099866770469)') AS points) a CROSS JOIN
         ways_vertices_pgr v
    ORDER BY a.points, dist;

通過查詢檢查EXPLAIN ANALYZE的輸出,以確切了解添加列時結果為何更改。 可能它使用的執行計划略有不同,這會影響行的順序。

DISTINCT ON根據定義是不確定的,這意味着結果可以在兩次執行之間改變。 PostgreSQL 9.6手冊

SELECT DISTINCT ON ...請注意,除非查詢在足夠的列上排序以保證到達DISTINCT過濾器的行的唯一順序,否則集合的“第一行”是不可預測的。 (在ORDER BY排序之后進行DISTINCT ON處理。)

按照戈登的建議添加ORDER BY應該會給您帶來可重復的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM