PostgreSQL - Paikkatietomies

Kiinteistötunnus muodosta toiseen PostgreSQL-tietokannassa

Kiinteistötietojärjestelmä (lyh. KTJ) on suomalaisen maaomaisuudenhallinnan perusrekisteri, joka sisältää tiedot kaikista Suomen valtakunnan alueella sijaitsevista kiinteistöistä. Kiinteistötietojärjestelmä sisältää mm. tiedon kiinteistön maantieteellisestä sijainnista ja ominaisuuksista (kiinteistörekisteri) sekä tiedot kiinteistön omistajasta/omistajista ja kiinnityksistä (lainhuuto- ja kiinnitysrekisteri).

Kiinteistötietojärjestelmän tietoja ylläpitävät Maanmittauslaitos ja kunnat. Kiinteistön kiinteistötietojärjestelmässä yksilöivä tunniste on nimeltään kiinteistötunnus.

Tässä artikkelissa tutustutaan tarkemmin kiinteistötunnuksen erilaisiin esitystapoihin ja siihen, millaisia ratkaisuja avoimen lähdekoodin tietokanta PostgreSQL voi tarjota kiinteistötunnusten esitystapojen välisiin muutoksiin.

Kiinteistötunnus ja sen muoto on määritelty laissa

Kiinteistötunnuksen muoto on määritelty laissa. Kiinteistötunnuksen koneluettava muoto on 14 merkkiä pitkä numerosarja. Kiinteistötunnus muodostuu kolme merkkiä pitkästä kuntanumerosta, kolme merkkiä pitkästä sijaintialuenumerosta, neljä merkkiä pitkästä ryhmänumerosta ja neljä numeroa pitkästä yksikkönumerosta. Koneluettavan muodon lisäksi käytetään eroteltua muotoa, jossa em. numerot erotellaan väliviivalla (-).

Asiaa on hyvä havainnollistaa esimerkin avulla. Kiinteistötunnuksen lyhyt eroteltu muoto näyttää tältä: 167-2-213-2. Sama kiinteistötunnus pitkässä muodossa näyttää puolestaan tältä: 16700202130002. Ihmissilmälle lyhyt muoto on helppolukuisempi, mutta tietokoneen on helpompi käsitellä lukujonoa, jossa merkkien määrä on vakio jokaisessa kiinteistötunnuksessa.

Muunnettaessa kiinteistötunnusta lyhyestä muodosta pitkään muotoon, merkkien väliin lisätään nollia varsinaisen numeron eteen. Pitkästä muodosta lyhyeen muunnettaessa nollat puolestaan jätetään pois. Nollien poisjättämiseen liittyy pari poikkeusta.

Kiinteistötunnus voi sisältää tapauksen, jossa peräkkäin on neljä nollaa (0000). Näissä tapauksissa neljän nollan muodostama (pitkässä muodossa) merkkijono merkitään lyhyessä muodossa yhdellä nollalla. Tällainen tilanne voi tulla vastaan ainoastaan ryhmä- ja yksikkönumeroiden kohdalla, jotka voivat olla nollia. Kunta- ja sijaintialuenumerot eivät voi koskaan olla nollia.

Kiinteistötunnus tietokannassa

Tietokantaan kiinteistötunnusta kannattaa tapauksesta riippuen sovitella joko numeerisessa muodossa tai tekstinä. Jälkimmäisen muodon käyttö on kannattavaa etenkin lyhyen muodon tapauksessa, jolloin numeroita erottava väliviiva aiheuttaa mahdollisimman vähän ongelmia.

Tässä artikkelissa esitetyt PostgreSQL-tietokannan funktiot toimivat tapauksessa, jossa kiinteistötunnus on tekstimuodossa. Mikäli käytössä on numeerinen esitystapa, tulee kiinteistötunnus muuntaa tekstimuotoon ennen funktioiden käyttämistä. Tietotyypin muunnos numeerisesta tekstiksi onnistuu kätevästi PostgreSQL-tietokannan CAST-toiminnolla. Ja mikäli PostgreSQL-tietokanta ei ole tuttu, niin kyseessä on avoimen lähdekoodin tietokanta, johon on saatavissa spatiaaliominaisuudet tarjoava PostGIS-lisäosa. Blogissani on useita kirjoituksia PostGIS-lisäosan käytöstä.

Eräs tapa kiinteistötunnuksen käsittelyyn tietokannassa on myös se, että sen räjäyttää osiin ja tallentaa tunnuksen osat omiin sarakkeisiinsa. Tästä on se etu, että kohteita on vaivattomampaa valita esimerkiksi vain tietyn sijaintialuenumeron (kylän) alueelta ilman, että tätä tietoa tarvitsee parsia esiin kokonaisesta kiinteistötunnuksesta.

Pitkästä lyhyeen

Ajamalla alla olevan SQL-komentosarjan esimerkiksi pgAdmin-tietokannanhallintatyökalun kyselyikkunassa, PostgreSQL-tietokantaan luodaan uusi muunna_kitu_lyhyeksi -niminen tietokantafunktio. Funktiolla onnistuu tekstimuotoisen kiinteistötunnuksen muunto pitkästä muodosta lyhyeen muotoon. Halutessaan luotua funktiota voi tarkastella tietokannan public-skeeman Functions-kohdan alta.

Sen syvemmin en tässä yhteydessä syvenny funktion toimintaperiaatteeseen. Sen verran on kuitenkin paikallaan todeta, että funktio yhdistelee muutamia PostgreSQL-tietokannan merkkijonon käsittelyyn tarkoitettuja funktiota. Funktio hanskaa lisäksi tapaukset joissa ryhmä- ja yksikkönumerot koostuvat ainoastaan nollista. Mikäli haluat lisätietoa funktion toiminnasta, laita vaikka alle kommenttia.

-- Paikkatietomiehen kiinteistötunnuksen pitkästä muodosta lyhyeen muuttava PostgreSQL-funktio
CREATE OR REPLACE FUNCTION muunna_kitu_lyhyeksi(kitu text) 
 RETURNS text 
 LANGUAGE 'sql'
AS $BODY$
SELECT
 CONCAT (
  -- kuntanumero
  TRIM (
   LEADING '0'
   FROM
   SUBSTRING(kitu,1,3)),
  '-',
  -- sijaintialuenumero
  TRIM (
   LEADING '0'
   FROM
   SUBSTRING(kitu,4,3)),
  '-',
  -- ryhmänumero
  CASE 
   WHEN SUBSTRING(kitu,7,4) LIKE '0000'
    THEN '0'
   ELSE
    TRIM (
    LEADING '0'
    FROM
    SUBSTRING(kitu,7,4))
  END,
  '-',
  -- yksikkönumero
  CASE 
   WHEN SUBSTRING(kitu,11,4) LIKE '0000'
    THEN '0'
   ELSE
    TRIM (
    LEADING '0'
    FROM
    SUBSTRING(kitu,11,4))
  END
 )
;
$BODY$;

Luotua funktiota voi käyttää esimerkiksi seuraavalla komennolla. Funktiota tulee kutsua parametrin kanssa. Parametriksi tulee antaa kiinteistötunnus pitkässä muodossa. Alla olevassa esimerkissä funktiolle annetaan parametriksi yksittäinen kiinteistötunnus (yksittäinen tekstiarvo annetaan SQL-kielessä ’-merkkien välissä). Yhtä hyvin parametriksi voidaan määritellä vaikkapa jonkin sarakkeen nimi. Kyselyn palauttama vastaus on esitetty kyselyn alla harmaalla.

SELECT muunna_kitu_lyhyeksi('16700202130002');
Kyselyn palauttama vastaus: 167-2-213-2

Ja lyhyestä pitkään

Ajamalla seuraavan SQL-komentosarjan kyselyikkunassa, PostgreSQL-tietokantaan luodaan uusi muunna_kitu_pitkaksi -niminen tietokantafunktio. Funktiolla onnistuu tekstimuotoisen kiinteistötunnuksen muunto lyhyestä muodosta pitkään muotoon. Halutessaan tätäkin funktiota voi tarkastella tietokannan public-skeeman Functions-kohdan alta. Funktio on rakenteeltaan edellistä yksinkertaisempi, sillä muunnettaessa kiinteistötunnusta lyhyestä pitkään muotoon, neljän nollan poikkeustilanteita ei tarvitse huomioida erikseen CASE-rakenteen avulla.

-- Paikkatietomiehen kiinteistötunnuksen lyhyestä muodosta pitkään muuttava PostgreSQL-funktio
CREATE OR REPLACE FUNCTION muunna_kitu_pitkaksi(kitu text) 
 RETURNS text 
 LANGUAGE 'sql'
AS $BODY$
SELECT
 CONCAT (
  -- kuntanumero
  LPAD (
   (split_part(kitu, '-', 1)), 3, '0'
  ),
  -- sijaintialuenumero
  LPAD (
   (split_part(kitu, '-', 2)), 3, '0'
  ),
  -- ryhmänumero
  LPAD (
   (split_part(kitu, '-', 3)), 4, '0'
  ),
  -- yksikkönumero
  LPAD (
   (split_part(kitu, '-', 4)), 4, '0'
  )
 )
;
$BODY$;

Luotua funktiota voi käyttää alla esitellyllä komennolla. Tätäkin funktiota tulee kutsua parametrin kanssa, joksi annetaan kiinteistötunnus lyhyessä muodossa. Tässä esimerkissä funktiolle annetaan parametriksi yksittäinen kiinteistötunnus ’-merkein erotettuna. Kyselyn palauttama vastaus on esitetty kyselyn alla harmaalla.

SELECT muunna_kitu_pitkaksi('167-2-213-2');  
Kyselyn palauttama vastaus: 16700202130002

Edellä esitetyt funktiot syntyivät erään työtehtävän sivutuotteena, jossa minun tuli yhdistää aineistoja eri muotoisten kiinteistötunnusten perusteella. Aikani ongelman kanssa taisteltuani (lue: melkoiset rimpsut PostgreSQL:n merkkijononkäsittelyfunktioita kyselyn olosuhde-ehdossa) päätin, että kirjoitan rimpsut SQL-funktioiden muotoon käyttääkseni niitä myöhemmin uudelleen.