![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
![]() Grupa: Zarejestrowani Postów: 1 116 Pomógł: 119 Dołączył: 10.05.2005 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Witam,
mam tabelę numery: Kod test=# \d numery Table "public.numery" Column | Type | Modifiers --------+---------+----------------------------------------------------- id | integer | not null default nextval('numery_id_seq'::regclass) numer | integer | grupa | integer | w której mam dane: Kod test=# select * from numery; id | numer | grupa ----+-------+------- 1 | 1 | 1 2 | 1 | 1 3 | 1 | 1 4 | 1 | 1 5 | 1 | 1 6 | 1 | 1 7 | 1 | 1 8 | 1 | 1 9 | 3 | 1 10 | 3 | 1 11 | 10 | 2 12 | 10 | 2 13 | 10 | 2 14 | 10 | 2 15 | 10 | 2 16 | 8 | 2 17 | 8 | 2 18 | 8 | 2 19 | 7 | 2 20 | 8 | 3 21 | 8 | 3 22 | 8 | 3 23 | 8 | 3 24 | 8 | 3 (24 rows) chcę teraz znaleźć dominantę (czyli wartość najcześciej się pojawiająca w grupie) dla każdej z grup, czyli aby wynik zapytania wylądał mniej więcej tak: Kod test=# select domin(numer), grupa from numery group by grupa; domin | grupa -------+------- 8 | 3 10 | 2 1 | 1 (3 rows) trafiłem na stronę 34.10. User-Defined Aggregates i tam po części jest napisane jak tworzyć własne funkcje agregujące, niestety nie mam pojęcia jak stworzyć funkcję wyliczającą dominantę. Robił ktoś własne metody agregujące? Pozdrawiam w pocie czoła... ale działa... nie chciało mi się ani "wyczyścić" z niepotrzebnych części kodu ani go optymalizować, może komuś się przyda to przyda, nic nie gwarantuję bo nie czuję się w tym języku dobrze... Kod CREATE OR REPLACE FUNCTION dominanta("input" anyarray) RETURNS integer AS $BODY$DECLARE tmp integer[][]; arr integer[][]; ret integer; firstRes integer; tmpInt integer; arrCount integer; tmpCount integer; found boolean; BEGIN ret := 0; -- array_upper(array, 1) zwraca count(array) arrCount := array_upper($1, 1); FOR i IN 1..arrCount LOOP -- aktualna wartosc w tablicy dla iteracji tmpInt := getArrayElem($1, i); found := false; IF tmp[1][1] IS NULL THEN tmpCount := 0; ELSE tmpCount := array_upper(tmp, 1); END IF; FOR j IN 1..tmpCount LOOP IF tmp[j][1] = tmpInt THEN tmp[j][2] := tmp[j][2] + 1; found := true; EXIT; END IF; END LOOP; IF found = false THEN tmp := tmp || ARRAY[[tmpInt, 1]]; END IF; END LOOP; tmpInt := 0; FOR i IN 1..array_upper(tmp, 1) LOOP IF tmpInt < tmp[i][2] THEN ret := tmp[i][1]; tmpInt := tmp[i][2]; END IF; END LOOP; RETURN ret; END;$BODY$ LANGUAGE 'plpgsql' IMMUTABLE STRICT; Pozdrawiam Cezar708 |
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 25.06.2025 - 20:29 |