Добавьте порядковый номер в новое поле на основе отсортированного списка по возрастанию (SQL в QGIS)

#sql #qgis

Вопрос:

У меня есть линейный (сегментированный дорожный) набор данных, где каждая дорога имеет уникальный код, но эта дорога может быть сегментирована. Я хочу добавить уникальный код (местоположение) и порядковый номер (на основе начальной цепочки сегмента) в новое поле (segment_id).

Мне это нужно в SQL-версии QGIS, которая разрешает только эти команды-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 в значение местоположения, чтобы получить местоположение.Сегмент#

Возможно ли это исключительно в 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
 

Если я изменю номер строки на другое поле, оно не объединится, а добавит два целых числа

введите описание изображения здесь

Если я изменю его на concat, он будет работать, но я все равно не смогу использовать RowNum или Row_Number, так как получу ту же ошибку (такого столбца нет).

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

Комментарии:

1. Я не совсем понимаю, к какому конечному результату вы стремитесь. Можете ли вы предоставить пример того, как должен выглядеть результат? Первая идея, которая приходит мне в голову, — использовать что-то вроде ROW_NUMBER() НАД (РАЗДЕЛЕНИЕМ ПО МЕСТОПОЛОЖЕНИЮ ….

2. Это последняя колонка таблицы. Таким образом, для fid 600, где местоположение равно 27, нам нужно, чтобы segment_id был 27,2, так как он начинается со 120 м, а для 601 он должен быть 27,1, так как это первый сегмент, начинающийся с 0 м.

Ответ №1:

Похоже, вам захочется использовать оконную функцию ROW_NUMBER (). Я просмотрел документацию, и она это подтверждает.

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

Что вы, скорее всего, захотите сделать, так это «ROW_NUMBER() НАД (РАЗДЕЛ ПО ПОРЯДКУ РАСПОЛОЖЕНИЯ ПО FID) КАК RN» в подзапросе. Затем приведите RN к varchar и соедините его с местоположением. Что-то вроде «ПРИВЕДЕНИЕ(местоположение как VARCHAR(30)) ‘.’ ПРИВЕДЕНИЕ(RN КАК 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
 

Комментарии:

1. Это в основном работает хорошо, но не выполняет конкатенацию правильно, чтобы получить Segment_ID. Я обновлю Q с помощью кода.

2. @GeorgeC, вам нужно поместить весь запрос в подзапрос. Т. Е. Выберите *, <вставить конкат здесь> ИЗ (Выберите … Номер строки из таблицы.)

3. Для справки, SQL выполняется с помощью наборов данных, которые он знает. В зависимости от порядка операций (как выполняется sql) «выбор» выполняется ближе к концу и, в целом, в целом. Если вы хотите, чтобы информация из этого выбора была объединена, вам нужно либо создать столбец внутри себя, либо выполнить дополнительный выбор (оболочку). Любой из наборов кода будет выглядеть немного сложнее, но, на мой взгляд, поднабор легче читать. Я обновил свой раздел ответов для вас.