【问题标题】:How to write id of nearby areas in PostgreSql?如何在 PostgreSql 中写入附近区域的 id?
【发布时间】:2019-11-13 18:22:37
【问题描述】:

请帮忙!

该数据库包含 WKB 格式的城市地理数据。 在d1, d2, d3(送货公司)列的每一行中,值为1 or 0。 1表示本市有送货。 0 表示没有。

如果在任何行的 d1 列中有0(没有送货),我需要找到这家公司最近(按距离)有送货的区域,并将该区域的 id 写在一个新的d1_nearest 列(如果该列已创建,则更新数据)。

同理,对于其他快递公司d2 in d2_nearest, d3 in d3_nearest。 如果设置了d1 = 1(表示该区域有投递),则d1_nearest="NULL"

源表:

|id   |name   |geom          |d1 |d2 |d3 |
|-----|-------|--------------|---|---|---|
|7499 |Rublevo|010300 ... B40|1  |0  |0  |
|7534 |Troitsk|010300 ... B40|1  |0  |0  |
|9629 |Maryino|010300 ... B40|1  |0  |0  |
|9937 |Vnukovo|010300 ... B40|1  |1  |0  |
|10724|Pihtino|010300 ... B40|1  |1  |0  |
|10996|Bobrovo|010300 ... B40|1  |1  |0  |

我的搜索结果是这样的:

|id   |name   |geom          |d1 |d2 |d3 |d1_nearest|d2_nearest|d3_nearest|
|-----|-------|--------------|---|---|---|----------|----------|----------|
|7499 |Rublevo|010300 ... B40|1  |0  |0  |NULL      |8248      |8248      |
|7534 |Troitsk|010300 ... B40|1  |0  |0  |NULL      |9937      |10723     |
|9629 |Maryino|010300 ... B40|1  |0  |0  |NULL      |9937      |10723     |
|9937 |Vnukovo|010300 ... B40|1  |1  |0  |NULL      |NULL      |10723     |
|10724|Pihtino|010300 ... B40|1  |1  |0  |NULL      |NULL      |10723     |
|10996|Bobrovo|010300 ... B40|1  |1  |0  |NULL      |NULL      |11022     |

等等

我这样做了,但是对于这个选项,我需要两个表。而且我还是不明白怎么给整个表做一个循环,给快递公司的每一列设置值……我不是很会编程。

请帮忙完成任务!

SELECT
t1.name As name,
t1.geom As geom,
t2.name As name,
t2.geom As geom,
ST_Distance (
ST_Transform (t1.geom :: geometry, 3857),
ST_Transform (t2.geom :: geometry, 3857)
) as dist
FROM cities11 As t1, cities10 As t2
WHERE t1.id = '7499' AND t1.id <> t2.id AND t2.d1 = '1'
ORDER BY ST_Distance (t1.geom, t2.geom)
LIMIT 1

来自this page的示例代码

Sample CSV

很多很多谢谢!!!

【问题讨论】:

    标签: postgresql postgis


    【解决方案1】:

    您是否尝试过使用CASE 条件来制作此过滤器?也许这个CTE 查询会进一步帮助你:

    WITH j AS (
    SELECT id,
      CASE WHEN d1 = 0 THEN 
          (SELECT id FROM t t2 WHERE d1 = 1
           ORDER BY ST_Distance(t1.geom,t2.geom) ASC LIMIT 1)
        ELSE NULL
      END AS d1_nearest,
      CASE WHEN d2 = 0 THEN 
          (SELECT id FROM t t2 WHERE d2 = 1
           ORDER BY ST_Distance(t1.geom,t2.geom) ASC LIMIT 1)
        ELSE NULL
      END AS d2_nearest,
      CASE WHEN d3 = 0 THEN 
          (SELECT id FROM t t2 WHERE d3 = 1
           ORDER BY ST_Distance(t1.geom,t2.geom) ASC LIMIT 1)
        ELSE NULL
      END AS d3_nearest
    FROM t t1
    )
    UPDATE t 
      SET d1_nearest = j.d1_nearest,d2_nearest = j.d2_nearest,d3_nearest = j.d3_nearest
    FROM j WHERE t.id = j.id;
    

    这是您更新后的表格:

    SELECT 
      id, name, d1, d2, d3, d1_nearest AS np1, d2_nearest AS np2, d3_nearest AS np3 
    FROM t ORDER BY id;    
    
      id   |              name              | d1 | d2 | d3 | np1  |  np2  |  np3  
    -------+--------------------------------+----+----+----+------+-------+-------
      6600 | Горки                          |  1 |  0 |  0 |      |  8248 |  7497
      6733 | Восточный                      |  1 |  0 |  0 |      |  8248 |  8248
      6734 | Милицейский посёлок            |  1 |  0 |  0 |      |  8248 |  8248
      6752 | Захарьино                      |  1 |  0 |  0 |      |  8248 |  8248
      6753 | Липки                          |  1 |  0 |  0 |      |  8248 |  8248
      7103 | Ермолино                       |  1 |  0 |  0 |      |  8248 |  7104
      7104 | Видное                         |  1 |  0 |  1 |      | 10715 |      
      7122 | Тарычёво                       |  1 |  0 |  1 |      |  8248 |      
      7214 | Котельники                     |  1 |  1 |  1 |      |       |      
      7309 | Красногорск                    |  1 |  1 |  1 |      |       |      
      7368 | Люберцы                        |  1 |  0 |  0 |      |  8248 |  8248
      7376 | Немчиновка                     |  0 |  1 |  1 | 8248 |       |      
      7377 | Трёхгорка                      |  1 |  0 |  1 |      |  8248 |      
      7381 | Мамоново                       |  1 |  0 |  0 |      |  8248 |  7391
      7386 | Никонорово                     |  1 |  0 |  1 |      |  8248 |      
      7389 | Лохино                         |  1 |  0 |  1 |      |  8248 |      
      7391 | Одинцово                       |  1 |  0 |  1 |      |  8248 |      
      7496 | Щербинка                       |  1 |  0 |  0 |      |  8248 |  8248
      7497 | Долгопрудный                   |  1 |  0 |  1 |      |  8248 |      
      7498 | Химки                          |  1 |  1 |  1 |      |       |      
      7499 | Рублёво                        |  1 |  0 |  0 |      |  8248 |  8248
      7523 | Дзержинский                    |  1 |  0 |  1 |      |  8248 |      
      7524 | Королёв                        |  1 |  0 |  0 |      |  8248 |  8248
      7534 | Троицк                         |  1 |  0 |  0 |      |  9937 | 10723
      7638 | Зеленоград                     |  1 |  0 |  0 |      |  7498 |  7498
      7802 | Реутов                         |  1 |  1 |  1 |      |       |      
      8026 | Заречье                        |  0 |  1 |  1 | 8248 |       |      
      8118 | Мякинино                       |  0 |  0 |  1 | 8248 |  8248 |      
      8128 | Михалково                      |  0 |  1 |  0 | 7309 |       |  7309
      8223 | Московский                     |  1 |  0 |  0 |      |  8248 |  8248
      8224 | Института Полиомиелита         |  1 |  0 |  0 |      |  9937 | 10723
      8245 | Лапшинка                       |  1 |  0 |  0 |      | 10724 | 10723
      8247 | Мосрентген                     |  0 |  0 |  1 | 8248 |  8248 |      
      8248 | Москва                         |  1 |  1 |  1 |      |       |      
      8506 | Новоивановское                 |  1 |  0 |  1 |      |  8248 |      
      8507 | Сетунь Малая                   |  0 |  0 |  1 | 8248 |  8248 |      
      8508 | Марфино                        |  1 |  1 |  1 |      |       |      
      8509 | Рождествено                    |  1 |  0 |  0 |      |  8248 |  8248
      8615 | Грибки                         |  1 |  0 |  0 |      |  8248 |  7497
      8730 | Коммунарка                     |  1 |  1 |  1 |      |       |      
      8731 | Газопровод                     |  1 |  1 |  1 |      |       |      
      8776 | Знамя Октября                  |  1 |  0 |  0 |      |  8248 |  8248
      8892 | Балашиха                       |  1 |  0 |  0 |      |  8248 |  8248
      9103 | Сапроново                      |  1 |  0 |  0 |      |  8248 |  7104
      9106 | Развилка                       |  1 |  1 |  1 |      |       |      
      9398 | Мытищи                         |  1 |  0 |  0 |      |  8248 |  8248
      9453 | Инновационный центр 'Сколково' |  0 |  1 |  0 | 7391 |       |  7391
      9629 | Марьино                        |  1 |  0 |  0 |      |  9937 | 10723
      9680 | Дрожжино                       |  1 |  1 |  0 |      |       |  8248
      9937 | Внуково                        |  1 |  1 |  0 |      |       | 10723
     10417 | Солнцево-Парк                  |  1 |  1 |  0 |      |       | 10723
     10541 | Молоково                       |  0 |  1 |  0 | 7523 |       |  7523
     10620 | Отрадное                       |  1 |  1 |  0 |      |       |  7498
     10710 | Битца                          |  0 |  0 |  1 | 8248 |  8248 |      
     10715 | совхоза имени Ленина           |  1 |  1 |  1 |      |       |      
     10723 | Рассказовка                    |  1 |  0 |  1 |      |  8248 |      
     10724 | Пыхтино                        |  1 |  1 |  0 |      |       | 10723
     10996 | Боброво                        |  1 |  1 |  0 |      |       | 11022
     11022 | Бутово                         |  1 |  1 |  1 |      |       |      
     11205 | Саларьево                      |  1 |  0 |  1 |      |  8248 |      
     11315 | Кнутово                        |  1 |  0 |  0 |      |  9937 | 10723
     11558 | Речник                         |  1 |  1 |  1 |      |       |      
     11643 | Путилково                      |  1 |  1 |  1 |      |       |      
     12229 | Виноградово                    |  1 |  0 |  0 |      |  8248 |  8248
    (64 Zeilen)
    

    【讨论】:

    • 这肯定会帮助我完成下一个任务,过滤仅北京的旅行
    • @arilwan 这可能对您的用例也有帮助,您可以创建具有更多/更少“流量”的区域的热图:stackoverflow.com/a/50845811/2275388
    • 哦,是的,我会对生成北京和波尔图城市的热图感兴趣。我将更详细地研究这个答案。你让我开心!
    • @arilwan 在这个答案中我使用 BBOX 而不是 4 个不同的参数稍微简化了函数:stackoverflow.com/a/59853843/2275388
    【解决方案2】:

    我不太确定您的表名和几何形状。但是,如果您将表名和 &lt;distance_function(c.geom, c2.geom)&gt; 替换为可以提供城市之间距离的名称,这可能会有所帮助:

    UPDATE cities c
    SET d1_nearest = (
        SELECT c2.id
        FROM cities c2
        WHERE c2.d1 = 1
        ORDER BY <distance_function(c.geom, c2.geom)>
        LIMIT 1
    ) WHERE d1 = 0;
    

    其他两列类似。当然,您需要提前创建新列。

    【讨论】:

    • 感谢回复!!我的知识不允许我编写一个函数来确定指定上下文中的位置。还是谢谢!
    • 您的问题代码中有类似于ST_Distance ( ST_Transform (c2.geom :: geometry, 3857), ST_Transform (c.geom :: geometry, 3857) ) 的内容。我不知道它有什么作用,但你可以尝试一下。我猜不需要编写自己的距离函数
    猜你喜欢
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 2022-12-01
    • 2020-04-02
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多