Ponieważ moje 'epokowe' dzieło działa, to w wolnych chwilach zabrałem się za... no, optymalizacja to za dużo powiedziane... za upiększenie kodu.
Problem 1:
Mamy pole numeric(9,2) o nazwie "staz"
Wartość w nim przechowywana zapisywana przed przecinkiem to lata (0-99), po przecinku to miesiące (0-11), np:
5,10 = 5 lat 10 miesięcy
2,00 = 2 lata
0,07 = 7 miesięcy
0,00 = wartość domyślna czyli użytkownik nic nie wpisał
Chciałbym wyświetlać te wartości 'opisowo' i bez wiodących zer, np.:
5,10 = "lat: 5, mies.: 10"
2,00 = "lat: 2"
0,07 = "mies.: 7"
0,00 = "-"
Celowo z 'lat' i 'mies.' przed wartościami, bo jak się przymierzyłem do odpowiedniego odmieniania (1 rok, 2 lata, 10 lat, 1 miesiąc, 2 miesiące, 10 miesięcy etc.) to się przeraziłem
Czy jest jakaś bardziej elegancka konstrukcja niż moje poniższe wypociny:
CASE
WHEN staz >= 1 AND MOD(staz,1) > 0
THEN
'lat: '
|| ltrim(split_part(to_char(staz::real,'00D00'), ',', 1), ' 0')
||
', mies.: '
|| ltrim(split_part(to_char(staz::real,'00D00'), ',', 2), ' 0')
WHEN staz >= 1 AND MOD(staz,1) = 0
THEN
'lat: '
|| ltrim(split_part(to_char(staz::real,'00D00'), ',', 1), ' 0')
WHEN staz > 0 AND staz < 1
THEN
'mies.: '
|| ltrim(split_part(to_char(staz::real,'00D00'), ',', 2), ' 0')
ELSE
'-'
END
???
Ponieważ są 4 pola tego typu i podobnego przeznaczenia, to ten przydługawy fragment kodu występuje w zapytaniu czterokrotnie - mało fajnie wygląda (ale działa!), może dałoby się go skrócić...?
Problem 2:
Mamy tabelę z adresami.
W niej są między innymi pola adres_opisowy, kod_pocztowy, poczta, miejscowosc, ulica, nr_domu, nr_lokalu.
Pole adres_opisowy to złączone i odpowiednio sformatowane przez aplikację wartości pozostałych pól.
Pola ulica, nr_domu i nr_lokalu są typu character varying, o długości odpowiednio 65, 10 i 10.
Aplikacja zezwala (to jest efekt zamierzony i poprawny), aby użytkownik wypełnił tylko pola kod_pocztowy, poczta i miejscowosc. Wówczas adres opisowy przyjmuje wartość np. "Berdyczów, 99-999 Berdyczów".
Wyświetlanie takiego adresu jako adresu do kontaktu jest bezsensowne, więc chciałbym to warunkowo pominąć.
Ale...
Jak wiadomo, są miejscowości bez ulic. Więc użytkownik wprowadza pola kod_pocztowy, poczta, miejscowosc i numer_domu (+ew. numer lokalu).
Wówczas adres opisowy przyjmuje wartość "Berdyczów 25, 99-999 Berdyczów" i jest jak najbardziej wartościowym adresem do kontaktu.
Mój warunek wygląda tak:
CASE
WHEN
(SELECT SAD.ulica
FROM adres SAD
WHERE
SAD.id = PSO.id
AND
relacja = 'xxxxxx') IS NOT NULL
OR
(SELECT SAD.nr_domu
FROM sy_adres SAD
WHERE
SAD.id = PSO.id
AND
relacja = 'xxxxxx') IS NOT NULL
OR
(SELECT SAD.nr_lokalu
FROM sy_adres SAD
WHERE
SAD.id = PSO.id
AND
relacja = 'xxxxxx') IS NOT NULL
THEN
...pierwszy raz wykonujemy na początku podzapytania, aby sprawdzić w połączeniu z innymi warunkami dotyczącymi innych tabel czy tworzyć nowy wiersz
...drugi raz wykonujemy w dalszej części podzapytania, aby wyświetlić adres
ELSE
''
END
Takich pól typu character varying związanych z adresem jest więcej: telefon, telefon komórkowy, fax, skrytka pocztowa (i chyba jeszcze coś...).
Aby obsłużyć je wszystkie, to kod, na dodatek wywoływany dwukrotnie, zaczyna się monstrualnie rozrastać...
Da się to w jakoś bardziej 'zwarty' sposób napisać?
Uwaga: PostgreSQL 8.3, nie mogę wykonywać żadnych działań ingerujących w bazę danych i jej konfigurację!