Sau khi tìm kiếm hơn tôi tìm thấy một trang liệt kê các pseudo-code bao Oracle thực hiện chức năng này tại địa chỉ:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions110.htm
tôi xác định để viết chức năng riêng của tôi trong vòng PG để bắt chước tính năng của Oracle.
Tôi tìm thấy một mảng sắp xếp kỹ thuật bởi David Fetter tại ::
http://postgres.cz/wiki/PostgreSQL_SQL_Tricks#General_array_sort
và
Sorting array elements
đây (cho rõ ràng) là mã của David:
CREATE OR REPLACE FUNCTION array_sort (ANYARRAY)
RETURNS ANYARRAY LANGUAGE SQL
AS $$
SELECT ARRAY(
SELECT $1[s.i] AS "foo"
FROM
generate_series(array_lower($1,1), array_upper($1,1)) AS s(i)
ORDER BY foo
);
$$;
Vì vậy, đây là hàm tôi viết e:
CREATE OR REPLACE FUNCTION percentile_cont(myarray real[], percentile real)
RETURNS real AS
$$
DECLARE
ary_cnt INTEGER;
row_num real;
crn real;
frn real;
calc_result real;
new_array real[];
BEGIN
ary_cnt = array_length(myarray,1);
row_num = 1 + (percentile * (ary_cnt - 1));
new_array = array_sort(myarray);
crn = ceiling(row_num);
frn = floor(row_num);
if crn = frn and frn = row_num then
calc_result = new_array[row_num];
else
calc_result = (crn - row_num) * new_array[frn]
+ (row_num - frn) * new_array[crn];
end if;
RETURN calc_result;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE;
Dưới đây là kết quả của một số thử nghiệm so sánh:
CREATE TABLE testdata
(
intcolumn bigint,
fltcolumn real
);
Đây là dữ liệu thử nghiệm:
insert into testdata(intcolumn, fltcolumn) values (5, 5.1345);
insert into testdata(intcolumn, fltcolumn) values (195, 195.1345);
insert into testdata(intcolumn, fltcolumn) values (1095, 1095.1345);
insert into testdata(intcolumn, fltcolumn) values (5995, 5995.1345);
insert into testdata(intcolumn, fltcolumn) values (15, 15.1345);
insert into testdata(intcolumn, fltcolumn) values (25, 25.1345);
insert into testdata(intcolumn, fltcolumn) values (495, 495.1345);
insert into testdata(intcolumn, fltcolumn) values (35, 35.1345);
insert into testdata(intcolumn, fltcolumn) values (695, 695.1345);
insert into testdata(intcolumn, fltcolumn) values (595, 595.1345);
insert into testdata(intcolumn, fltcolumn) values (35, 35.1345);
insert into testdata(intcolumn, fltcolumn) values (30195, 30195.1345);
insert into testdata(intcolumn, fltcolumn) values (165, 165.1345);
insert into testdata(intcolumn, fltcolumn) values (65, 65.1345);
insert into testdata(intcolumn, fltcolumn) values (955, 955.1345);
insert into testdata(intcolumn, fltcolumn) values (135, 135.1345);
insert into testdata(intcolumn, fltcolumn) values (19195, 19195.1345);
insert into testdata(intcolumn, fltcolumn) values (145, 145.1345);
insert into testdata(intcolumn, fltcolumn) values (85, 85.1345);
insert into testdata(intcolumn, fltcolumn) values (455, 455.1345);
Đây là kết quả so sánh:
ORACLE RESULTS
ORACLE RESULTS
select percentile_cont(.25) within group (order by fltcolumn asc) myresult
from testdata;
select percentile_cont(.75) within group (order by fltcolumn asc) myresult
from testdata;
myresult
- - - - - - - -
57.6345
myresult
- - - - - - - -
760.1345
POSTGRESQL RESULTS
POSTGRESQL RESULTS
select percentile_cont(array_agg(fltcolumn), 0.25) as myresult
from testdata;
select percentile_cont(array_agg(fltcolumn), 0.75) as myresult
from testdata;
myresult
real
57.6345
myresult
real
760.135
Tôi hy vọng điều này sẽ giúp ai đó o ut bởi không cần phải tái tạo lại bánh xe.
Tận hưởng! Ray Harris
bạn có thể tránh được bằng cách sử dụng arroy_sort ORDER BY. Nó thực sự nhanh hơn một chút so với array_sort. – echo
Tôi đã sử dụng chức năng này và cập nhật cơ sở dữ liệu của mình. Có một hàm có cùng tên bắt đầu bằng 9.4 và có xung đột giữa hai hàm do đặt tên giống nhau và cách chúng được triển khai. Điều này xảy ra sau khi tôi di chuyển từ 9,3 đến 9,6. –