Postgresql
在 PostgreSQL 中,是否有類型安全的 first() 聚合函式?
我正在尋找一個**
first()
**聚合函式。在這裡,我發現了一些幾乎可以工作的東西:
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 );
問題是當一
varchar(n)
列通過first()
函式時,它被轉換為簡單的varchar
(沒有大小修飾符)。嘗試在函式中返回查詢 asRETURNS SETOF anyelement
,我收到以下錯誤:ERROR: structure of query does not match function result type Estado de SQL:42804 Detalhe:Returned type character varying does not match expected type character varying(40) in column 2. Contexto:PL/pgSQL function vsr_table_at_time(anyelement,timestamp without time zone) line 31 at RETURN QUERY
在同一個 wiki 頁面中,有一個指向該函式的C 版本的連結,該函式將替換上述內容。我不知道如何安裝它,但我想知道這個版本是否可以解決我的問題。
同時,有沒有辦法可以更改上述函式,使其返回與輸入列完全相同的類型?
DISTINCT ON()
順便說一句,這正是
DISTINCT ON()
(不要與 混淆DISTINCT
)
SELECT DISTINCT ON ( expression [, ...] )
只保留給定表達式計算結果為 equal 的每組行的第一行。DISTINCT ON
表達式使用與 for 相同的規則進行解釋(ORDER BY
見上文)。ORDER BY
請注意,除非用於確保所需的行首先出現,否則每組的“第一行”是不可預測的。例如所以如果你要寫,
SELECT myFirstAgg(z) FROM foo GROUP BY x,y;
這是有效的
SELECT DISTINCT ON(x,y) z FROM foo; -- ORDER BY z;
因為它需要第一個
z
。有兩個重要的區別,
- 您還可以選擇其他列,而無需進一步聚合。
SELECT DISTINCT ON(x,y) z, k, r, t, v FROM foo; -- ORDER BY z, k, r, t, v;
- 因為沒有
GROUP BY
你不能使用(真正的)聚合。CREATE TABLE foo AS SELECT * FROM ( VALUES (1,2,3), (1,2,4), (1,2,5) ) AS t(x,y,z); SELECT DISTINCT ON (x,y) z, sum(z) FROM foo; -- fails, as you should expect. SELECT DISTINCT ON (x,y) z, sum(z) FROM foo; -- would not otherwise fail. SELECT myFirstAgg(z), sum(z) FROM foo GROUP BY x,y;
不要忘記
ORDER BY
另外,雖然我沒有加粗,但我現在將
請注意,除非使用 ORDER BY 確保所需的行首先出現,否則每組的“第一行”是不可預測的。例如
始終使用
ORDER BY
withDISTINCT ON
使用有序集聚合函式
first_value
我想很多人都在尋找Ordered-Set Aggregate Functions。只是想把它扔出去。如果函式存在,它看起來像這樣:SELECT a, b, first_value() WITHIN GROUP (ORDER BY z) FROM foo GROUP BY a,b;
但是,唉,你可以做到這一點。
SELECT a, b, percentile_disc(0) WITHIN GROUP (ORDER BY z) FROM foo GROUP BY a,b;