Volgnummering in gefilterde laag in QGIS

Hallo,

Ik heb in QGIS een attribuuttabel met 4 kolommen: fid, Route, Street_seg en seqnr_lbl. Route heeft altijd dezelfde waarde, in dit geval ‘108’. De kolom “Street_seg” bevat volgnummers van 1 t/m xxx (laatste rij). Maar, er zit een filter op de data, waardoor niet alle “Street_seg” waarden in deze tabel voorkomen. In het voorbeeld bijvoorbeeld de waarden 82 t/m 97.

Wat ik vervolgens wil, is met de gefilterde dataset de kolom “seqnr_lbl” vullen met opeenvolgende waarden, dus 1 t/m xx. Analoog dus aan de “Street_seg” waarden, en in dezelfde volgorde, maar dan uiteraard degene die niet gefilterd zijn overslaan.

Na wat gezoek ben ik erachter gekomen dat je wat met arrays kan stoeien. Bijvoorbeeld in de Field Calculator dit gebruiken:

array_find(array_agg($id, “Route”),$id) + 1

Bovenstaande blijkt inderdaad te werken in mijn geval. Maarrrr … het is wel tricky. Het werkt, mits in de tabel zelf de “Street_seg” kolom al in de goede volgorde staat. Er wordt namelijk niks gesorteerd in deze expressie.

Ik zou het graag wat degelijker doen, door in de expressie ook de sortering op het veld “Street_seg” te maken, zodat het gegarandeerd goed gaat. Dus iets met “array_sort” o.i.d.
Maar dat is me dus nog niet gelukt.

Iemand een geniaal idee?!

Misschien met array_sort() ertussen?

Ja, dat is het: dat “ertussen”.
Ik heb daar van alles mee geëxperimenteerd, maar ik vind nergens een goed voorbeeld hoe dat “ertussen” dan werkt.

Heb je een link naar een klein demo datasetje?

Sorry, las iets te snel overheen dat je dat al genoemd had :blush:

Hoi Raymond,

Hier een linkje (via Dropbox).

datasetje

Je ziet hier dat “seqnr_lbl” deels is ingevuld (met de waarde 1), deels leeg is.
Het gaat erom dat ik degene waar nu 1 in staat vul met opvolgende nummers 1 t/m 194, op basis van de volgorde die in “Street_seg” staat.

Zoals aangegeven: in dit geval lukt dat wel omdat de tabel al “goed” gesorteerd is, maar ik zou graag in de Calculate expressie die sortering ook daadwerkelijk meebakken zodat het gegarandeerd goed gaat.

In PostGIS / PostgreSQL kan dat vrij eenvoudig in een subquery, maar ja, dat “mag” nu even niet :wink:

Helaas Willem, na een uurtje prutsen ben ik er nog niet uit. De expression editor was ik al gauw zat, dus toen ben ik het met een virtual layer gaan proberen. Daar kun je namelijk wel subqueries doen. Was er bijna met deze query:

select tds.fid as fid, tds.rowid as new_seqnr_lbl
from (
select *
from testdatasetje
where seqnr_lbl = 1
order by Street_seg
) tds

Maar in de kolom “new_seqnr_lbl” komen alleen maar NULL values. (Misschien een bug in QGIS?)

Persoonlijk zou ik trouwens gauw een python scriptje maken denk ik.

Groet,
Raymond

Ha Raymond,

Dank voor het uitzoeken.
Inderdaad vreemd dat die kolom leeg blijft.
Ik heb jouw query ook rechtstreeks in de Geopackage geprobeerd (ook via DB Manager), maar krijg ook NULL values terug.

Jouw oplossing lijkt erg veel op hoe ik het in PostGIS zou oplossen:

select tds.fid as fid, tds.street_seg, row_number() over () as seq_lb_nw
from (
select *
from test.route108
where seqnr_lbl = 1
order by street_seg
) tds

En dan werkt het inderdaad wel zoals ik verwacht, mét correct ingevulde “seq_lb_nw” waarden.

Anyway, ik probeer zelf nog wat te prutsen, maar mocht het geniale idee nog langs komen (zonder PostGIS, zonder Python) dan hou ik me aanbevolen!

Groet,
Willem

Ah, toch nog wat bruikbaars gevonden en wil dat toch even als oplossing delen:

array_find(array_agg($id, “Route”, “seqnr_lbl” IS NOT NULL, “Street_seg”), $id) + 1

Feitelijk de expressie die ik al had gevonden, met de array_agg functie. Deze kun je echter meer argumenten meegeven zie ik nu: naast het $id ook de volgende zaken:

  1. group by (in dit geval “Route”, die is in alle rijen gelijk)
  2. filter
  3. en, last but not least, een ‘sort item’. Dus als 4e argument een sorteerkolom (in dit geval “Street_seg”) opgeven

Dat doet 't wel.
Mooie in mijn geval is dat het filteren zelf meteen in de expressie meegebakken zit. Zal mijn klant blij mee zijn :wink:

Nogmaals, jullie bedankt voor het meedenken!

2 likes

Ik dacht eerst dat het kwam omdat het veld new_seqnr_lbl een alfanumeriek veld wordt. Maar ook bij het forceren naar een integer blijft het veld leeg. Ook bij het specifiek casten van het rowid als integer. Het lijkt me erop te duiden dat het rowid dan nog niet bekend is, anders was het veld automatisch integer geweest denk ik.

Misschien geen bug maar wel een andere implementatie van SQL door QGIS?