Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

PostgreSQL tương đương với hàm PERCENTILE_CONT của Oracle

Sau khi tìm kiếm nhiều hơn, tôi đã tìm thấy một trang liệt kê mã giả về cách Oracle triển khai chức năng này tại:

http://docs.oracle.com/cd/B19306_01 /server.102/b14200/functions110.htm

Tôi quyết định viết hàm của riêng mình trong PG để bắt chước tính năng của Oracle.

Tôi đã tìm thấy một kỹ thuật sắp xếp mảng của David Fetter tại ::

http://postgres.cz/wiki/PostgreSQL_SQL_Tricks#General_array_sort

Sắp xếp các phần tử mảng

Đây (để 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à chức năng tôi đã viết:

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 ích cho ai đó bằng cách không phải phát minh lại bánh xe.

Hãy tận hưởng! Ray Harris



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để tách một phân vùng khỏi một bảng và gắn nó vào một bảng khác trong oracle?

  2. Cập nhật với sau khi chèn trình kích hoạt trên cùng một bảng

  3. Khi nào tôi cần sử dụng dấu chấm phẩy và dấu gạch chéo trong Oracle SQL?

  4. Làm thế nào để lấy ngày có hiệu lực hiện tại trong Oracle?

  5. Cách rõ ràng nhất để xây dựng một chuỗi SQL trong Java