Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PostgreSQL] Własna funkcja agregująca, obliczenie wartości najczęściej pojawiającej się (dominanty)
Cezar708
post 3.03.2009, 09:13:06
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
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 25.06.2025 - 20:29