Ponowne napisanie pełnego pytania
Szukam funkcji agregującej First ().
Tutaj znalazłem coś, co prawie działa:
CREATE OR REPLACE FUNCTION public.first_agg ( anyelement, anyelement )
RETURNS anyelement LANGUAGE sql IMMUTABLE STRICT AS $$
SELECT $1;
$$;
-- And then wrap an aggregate around it
CREATE AGGREGATE public.first (
sfunc = public.first_agg,
basetype = anyelement,
stype = anyelement
);
Problem polega na tym, że gdy kolumna varchar (n) przechodzi przez pierwszą funkcję (), jest konwertowana na prosty varchar (bez rozmiaru). Próbuję zwrócić zapytanie w funkcji jako ZWRACAĆ SETOF anyelement, otrzymuję następujący błąd:
BŁĄD: struktura zapytania nie zgadza się z typem wyniku funkcji Estado de SQL: 42804 Detalhe: Zmienna postać zwracanego typu nie pasuje do oczekiwanej zmienności typu (40) w kolumnie 2. Kontekst: Funkcja PL / pgSQL vsr_table_at_time (dowolny element, znacznik czasu bez strefy czasowej ) wiersz 31 w ZWROTNEJ KWESTII
Na tej samej stronie wiki znajduje się link do wersji C funkcji , która zastąpiłaby powyższą. Nie wiem, jak go zainstalować, ale zastanawiam się, czy ta wersja mogłaby rozwiązać mój problem.
Czy w międzyczasie mogę zmienić powyższą funkcję, aby zwracała dokładnie ten sam typ kolumny wejściowej?
źródło
DISTINCT ON
nie zadziała w tym przypadku. To nie jest funkcja agregująca, w rzeczywistości filtrujesz dane, więc możesz to zrobić tylko raz.Tak, odkryłem łatwy sposób korzystania z twojej skrzynki, używając niektórych funkcji w PostgreSQL 9.4+
Zobaczmy ten przykład:
Mam nadzieję, że ci to pomoże.
źródło
DOMAIN
typami danych lub innymi małymi wyjątkami. Jest również o wiele bardziej skomplikowany i czasochłonny, tworząc tablicę całego zestawu danych. Prostym rozwiązaniem byłoby utworzenie niestandardowego agregatu, ale jak dotąd nie znalazłem idealnego rozwiązania nawet z tym. Funkcje okien również są złe, ponieważ nie można ich używać w taki sam sposób, jak można używać agregatów (z instrukcjami FILTER lub w CROSS JOIN LATERAL)Nie jest to bezpośrednia odpowiedź na twoje pytanie, ale powinieneś wypróbować funkcję
first_value
okna. Działa to tak:);
Następnie, jeśli chcesz pierwszy element w każdej
cat
(kategorii), zapytaj w ten sposób:lub:
źródło
select distinct x, first_value(y) over (partition by x), first_value(z) over (partition by x) from ...
. Prawdopodobnie nieefektywny, ale wystarczający, abym mógł zająć się prototypowaniem. Zdecydowanie jednak coś do odwiedzenia!