【问题标题】:Add sequential number to new field based on a sorted ascending list (SQL in QGIS)根据排序的升序列表将序号添加到新字段(QGIS中的SQL)
【发布时间】:2021-11-20 11:51:48
【问题描述】:

我有一个线(分段道路)数据集,其中每条道路都有一个唯一的代码,但这条道路可能是分段的。我想将唯一代码(位置)和序号(基于段的起始里程)添加到新字段(段_id)。

我需要它在 QGIS 风格的 SQL 中,只允许这些命令 -https://sqlite.org/lang.html?

下面的示例在最后一个(Segment_ID)列中包含我想要结束的字段

fid RoadMntnc   Location    Segments    Start_Chainage  Segment_ID
640 Albatross_Cl    3   1   0   3.1
606 Allamanda_St    4   1   0   4.1
620 Barrbal_Dr  25  5   0   25.1
624 Barrbal_Dr  25  5   50  25.2
628 Barrbal_Dr  25  5   130 25.3
1092    Barrbal_Dr  25  5   180 25.4
1093    Barrbal_Dr  25  5   250 25.5
600 Bayil_Dr    27  2   120 27.2
601 Bayil_Dr    27  2   0   27.1

我们需要按位置分组,然后为每个组获取 Start_Chainage 的升序列表,然后将 1-x 插入位置值以获取 Location.Segment#

这可能纯粹在 SQL 中实现,还是我需要使用 Python?

==== 更新的代码示例基于 QuestionGuyBob 的建议

select ROW_NUMBER () OVER (
    PARTITION BY Location
    ORDER BY Start_Chainage
    ) RowNum, Location, RoadMntnc, Segments,
 CAST(Location as VARCHAR(30))+ '.'+Cast(RowNum as VARCHAR(30))  AS Segment_ID
    from test_simple_roads

报错

Query preparation error on PRAGMA table_info(_tview): no such column: RowNum

如果我将 RowNum 更改为另一个字段,它不会连接而是将两个整数相加

如果我将其更改为 concat 它可以工作,但我仍然无法使用 RowNum 或 Row_Number,因为我得到了相同的错误(没有这样的列)。

concat(Location, '.',RowNum)  AS Segment_ID

【问题讨论】:

  • 我并没有完全看到您的最终目标是什么。你能提供一个输出应该是什么样子的样本吗?我想到的第一个想法是使用类似 ROW_NUMBER() OVER (PARTITION BY LOCATION ....
  • 这是表格的最后一列。因此,对于位置为 27 的 fid 600,我们需要 segment_id 为 27.2,因为它从 120m 开始,对于 601,它应该是 27.1,因为它是从 0m 开始的第一段。

标签: sql qgis


【解决方案1】:

您似乎想要使用 ROW_NUMBER() 窗口函数。我查看了文档,它确实支持它。

https://www.sqlite.org/windowfunctions.html#built_in_window_functions

您最可能想要做的是在子选择中“ROW_NUMBER() OVER (PARTITION BY LOCATION ORDER BY FID) AS RN”。然后将 RN 转换为 varchar 并将其连接到位置。像“CAST(位置为 VARCHAR(30))+'。' + CAST(RN AS VARCHAR(30)) 作为 Segment_ID

    SELECT
    *
    ,CAST(Location as VARCHAR(30))+ '.'+Cast(RowNum as VARCHAR(30))  AS Segment_ID
FROM
    (
    SELECT 
    ROW_NUMBER () OVER (
    PARTITION BY Location
    ORDER BY Start_Chainage
    ) RowNum, Location, RoadMntnc, Segments
 
    from test_simple_roads) AS TEST

【讨论】:

  • 大多数情况下效果很好,但它没有正确连接以获得 Segment_ID。我将用代码更新 Q。
  • @GeorgeC,您需要将整个查询放在子选择中。 IE。 Select *, FROM (Select ... Row_number from table.)
  • 作为参考,SQL 通过它知道的数据集执行。根据操作顺序(如何执行 sql),“选择”在接近尾声时执行,并且通常作为一个整体执行。当您希望从该选择中连接信息时,您需要在其自身内构建列或执行子选择(包装器)。在我看来,任何一组代码都会看起来有点复杂,但子选择更容易阅读。我为你更新了我的答案部分。
猜你喜欢
  • 2015-08-12
  • 2014-06-13
  • 2020-10-01
  • 2020-09-27
  • 2020-06-30
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
  • 1970-01-01
相关资源
最近更新 更多