SQL FUNCTION to compute MEDIAN

Hi
Just as we use MAX and MIN to compute the maximum and minimum values using SELECT query in SQL, does anyone know of a direct/indirect function/method to calculate the MEDIAN of a given set of values. Powerbuilder provides median function. I am looking forward to doing this using SQL/PLSQL.

CREATE PROCEDURE mymedian (tbl_name IN VARCHAR2,
                 col_name IN VARCHAR2,
                 rows_at_a_time IN NUMBER DEFAULT 10,
                 where_clause IN VARCHAR2 DEFAULT NULL) IS
/* Procedure to return Median value of a column in a given table */
/* Parameters                                                   */
/* tbl_name          name of table to use                       */
/* column_name       column to calculate median for             */
/* where_clause      SQL where clause without the WHERE         */
/* rows_at_a_time    number of rows to fetch into array at once */
/* If odd number of rows returns calculates average of the two  */
/* middle numbers, otherwise returns middle number.             */
f_cur INTEGER;
sql_stmnt VARCHAR2(2000);
u_tbl DBMS_SQL.Number_Table;
rows_returned NUMBER;
median_count NUMBER;
rval NUMBER;
BEGIN
   DBMS_OUTPUT.Enable(2000);
   /* Build SQL statement */
   sql_stmnt := 'SELECT '||col_name||' FROM '||tbl_name;
   IF where_clause IS NOT NULL THEN
      sql_stmnt := sql_stmnt ||' WHERE '||where_clause;
   END IF;
   sql_stmnt := sql_stmnt||' ORDER BY '||col_name;
   f_cur := DBMS_SQL.Open_Cursor;
   DBMS_SQL.Parse(f_cur,sql_stmnt,1);
   DBMS_SQL.Define_Array(f_cur,1,u_tbl,rows_at_a_time,1);
   rows_returned := DBMS_SQL.Execute(f_cur);
   /* Step through cursor getting rows_at_a_time rows */
   LOOP
      rows_returned := DBMS_SQL.Fetch_Rows(f_cur);
      DBMS_SQL.Column_Value(f_cur,1,u_tbl);
      EXIT WHEN rows_returned <> rows_at_a_time;
   END LOOP;
   DBMS_SQL.Close_Cursor(f_cur);
   median_count := u_tbl.Count;
   IF MOD(median_count,2) = 0 THEN
      rval := (u_tbl(median_count/2) + u_tbl((median_count/2) + 1))/2;
   ELSE
      rval := u_tbl(CEIL(median_count/2));
   END IF;
   DBMS_OUTPUT.Put_Line ('Median of column '||col_name||' for table '||
                         tbl_name||' is '||rval);
EXCEPTION WHEN OTHERS THEN
   IF DBMS_SQL.Is_Open(f_cur) THEN
      DBMS_SQL.Close_Cursor(f_cur);
      DBMS_OUTPUT.Put_Line('Error: '||sqlerrm);
   END IF;
END;Set serveroutput on before calling this proc.

Similar Messages

  • PL/SQL function in datamodel query

    Hi All,
    I have the following problem:
    I have a query Q1 returning a few rows. In the group G1 using this query Q1 i have a computed field returning a number NUM_1.
    select col_1, col_2 from table_1;
    So the output looks like:
    row 1 col_1 col_2 NUM_1_1
    row n col_1n col_2n NUM_1_n
    I want to order these rows by the calculated column NUM_1 the highest first.
    I know i can't order by a calculated column but can i do it by using a pl/sql function in the query to calculate the NUM_1?
    Like:
    select col_1, col_2, function(x) NUM_1 from table_1;
    And where should i create this function? Can it be done in the program unit section or do i have to create a library?
    Best regards,
    Snoesky

    Oke, i have created a break group on the calculated field.
    Ordering works fine now.
    I have an additional question:
    Is it possible to dynamically order this break (column) group? Meaning thru a parameter to tell the ordering to be descending or ascending.
    Regards,
    Snoesky

  • Problem with PL/SQL Function Body

    Hi,
    I'm getting the following error, when i run the report.
    I'm trying to fetch a year value from a table based on a parameter value ":P33_YEAR"
    ORA-01403: no data found
    Error ERR-1904 Unable to compute item default: type = Function Body computation_type= DECLARE FY VARCHAR2(6); BEGIN SELECT DISTINCT YEAR1 INTO FY FROM REP WHERE YEAR = TRIM(:P33_YEAR);
    RETURN FY; END;.
    I have written this code in a PL/SQL Function Body for a Hidden item.
    Please let me know whats wrong with this code?
    Thanks
    CK
    Message was edited by:
    user536304

    Your code is in a default value for an item, right?
    You need to make sure :P33_YEAR is not null and handle the error in the PL/SQL if it is.
    How is P33_YEAR populated? do you pass it in? check to see if it is making it there..
    Message was edited by:
    Bill Carlisle

  • SQL, PL/SQL Expression and PL/SQL function

    In a Post Calculation Computation field I wanted the following computation:
    if B is X
    then
    field = A
    else
    field = B
    end if;
    or as a decode
    Decode(B,X,A,B)
    I could not get this to work so I wrote a database function that simulates the decode. So when I put:
    My_decode(B,X,A,B)
    in the field it did work.
    Basically I am not sure what kind of code one is expected to put into SQL, PL/SQL Expression and PL/SQL function fields. Can someone give an example of each? Also the APEX help is sometimes incorrect.
    For example if you click the "Post Calculation Computation" label it says:
    The For example, if this item is named P1_X, you could use post calculation expressions such as UPPER(:P1_X), INITCAP(:P2_Y), MIN(:P1_X,:P2_Y-200), NVL(:P1_X,:P2_Y), or a function call such as return my_func(:P1_X); to set the final value of the item.
    But if you put return my_func(:P1_X); in the field you get an error. It should be just my_func(:P1_X);
    thanks Rene

    DECODE is only available in SQL, so would have to be used in a SQL Expression.Yes, that's what APEX keeps telling me when I use in in a field that has "SQL or PL/SQL expression" above it. So what do you put in the field?

  • Demonstrating PL/SQL Functions Using SQL Developer

    Good afternoon,
    I'm starting to write some PL/SQL functions to replace some of the SQL that I use most frequently.  A couple of very simple examples would be:
    create or replace function func_test (p_1 number) return number
    is
    x number;
    y number;
    begin
    x :=1;
    y :=2;
    return p_1 * x * y;
    end func_test;
    create or replace function func_test2 (p_1 varchar2) return varchar2
    is
    return_val varchar2(10);
    begin
    select p_1 into return_val from dual;
    return return_val;
    end func_test2;
    However, at my workplace I haven't been granted create function privileges yet until I can demonstrate some examples, which is understandable.
    For the time being, without these privileges, is there a way I can build/test functions in principle locally using SQL Developer without the need to write the functions to our database? I.e. can I demonstrate the above in SQL Developer, but without wrapping in create or replace syntax?
    I hope this isn't too vague.
    Using Oracle 11gR2 (not logged in to workplace database at the moment for specific version no.)
    SQL Developer 3.4
    Thanks,
    TP

    sb92075 02-Nov-2013 19:12 (in response to TinyPenguin)
    populating test DB with data is a solvable problem.
    You don't need client data to test code (functions).
    You only need sample test data; which generally is less than a few dozen records per table.
    Absolutely, of course. Our client database is pretty messy though, and includes data prior to the implementation of more recent business rules that I need to take account of. Useful perspective though, thanks.
    rp0428 02-Nov-2013 19:14 (in response to TinyPenguin)
    Sure, but then I wouldn't have access to all the data in our client database to test functions under various circumstances.
    Huh? Why not? It's your database so what keeps you from creating a database link to your client database where all the data is?
    Also, I suppose it's not good practice to constantly write/replace/drop functions to/from a database when developing them? Better to test the function in principle and then write to the database?
    Huh? Why not? What you think a dev database is for if not for development?
    Based on your two posts so far in this thread it's understandable why they don't want to give you privileges yet. Those sample 'functions' you posted are NOT a good use for functions.
    In sql developer you can just create and save the queries you use most often. There is no need to create functions for that.
    But if you do need an anonymous function now and then just create one using sql*plus syntax:
    Our IT department are pretty sensitive about how they allow access, even to the dev environment. As you've identified, I'm not naturally a programmer so the option to play around with the data to develop some representative examples about how we can simplify and devolve SQL reporting to more members of staff is useful to me. I just wrote those two function quickly for the purpose of posting some sample data, which I thought would be helpful. Thanks for illustrating how to return their output using an anonymous block.
    FrankKulash 02-Nov-2013 19:13 (in response to TinyPenguin)
    Hi,
    The obvious solution is to get the privileges.  If your employer really wants you to do something, they need to give you the necessary privileges to do it.  It's silly for them to tell you to do something, but refuse to let you do it.
    Failing that, you can install Oracle on your own machine, as suggested above.  It's free and legitimate if you're only using it for learning and developing.  Oracle Express Edition is very easy to install.
    As a last resort, you can write functions and procedures that are local to an anonymous block, like this:
    Thanks Frank. Yeah I'm going to speak with our DBA next week about privileges. I've got XE/SQL Developer installed on my own computer - I wrote those sample functions using them - I just wasn't sure how to call/return anonymous blocks as both you and rp identified to develop at work as an interim solution.
    Thanks a lot All,
    TP.

  • How can i make a pl/sql function for BLOB datatype

    hi..anyone here who is very familiar about BLOB datatype. i have a COLUMN_ID, COLUMN_A in a certain TABLE_1. COLUMN_A is blob datatype that contains almost 250,000rows
    SQL>select column_A from table_1 where column_id=1234567
    column_A
    00000001000000010000000606D4E833074B69EC06D4E91F074CO18406D50C58074C031E
    how can i make a user-defined function to compute and convert this blob datatype into decimal length value. this hex value are points in the map.. the function must contain
    1.get the length of a blob then
    2.convert blob to variable hexadecimal characters by parsing it into 8
    3.to_number function or other function used to convert haxadecimal characters to decimal numbers
    4.phythagorean formula to compute length between two points. this is the formula i think LENGTH =
    SQRT(power((coordinate_x-prev_coordinate_x),2)+power((coordinate_y-prev_y),2));
    after this when i type this
    SQL>select user_function(column_A) from table_1 where column_id=1234567
    user_functions(column_A)
    --output length will be in decimal value already
    the function will goes like this
    step1 is to get the blob length
    00000001000000010000000606D4E833074B69EC06D4E91F074CO18406D50C58074C031E
    step2 is parsing of data by eights
    00000001 =>1
    00000001 =>1
    00000006 =>6 (number of coordinates)
    06D4E833 => X1
    074B69EC => Y1
    06D4E91F => X2
    074CO184 => Y2
    06D50C58 => X3
    074C031E => Y3
    step3 to_number function used to convert hex char to decimal
    step4 compute by phytagorean (NOTE ! when computing length the third parsed eight will tell how many coordinates are there..the number of coordinates is ranging from 2 up to E..above example shows 6 coordinates so it means
    LENGTH1 =
    SQRT(power((X2-X1),2)+power((Y2-Y1),2));
    LENGTH2=
    SQRT(power((X3-X2),2)+power((Y3-Y2),2));
    TOTAL LENGTH=LENGTH1 + LENGTH2
    thanks

    its my first time to use that.There's got to be a first tiem for anything. Be brave.
    btw if theres more easy suggestion pls feel free..Well of course the easiest solution would be if the calling program passed in the parameters as separate arguments instead of glomming them together in a string that has to be parsed. This sort of kluj really ought not to have survived into C21.
    Cheers, APC

  • PL/SQL Function Result Cache?

    Hi all,
    As we know, there's a new feature in 11g, called 'result cache', this 'result cache' can be shared throughout the whole instance, but if I got it right, only sql query result and function return value are cached, right? how about the store procedure, I mean, procedure also has its 'return value'--the output parameter, could it benefit from this new feature?
    Another question is, if my PL/SQL Function just retrieves the table and returns the result without any complicated calculation, is it necessary to enable the 'result cache' mechanism on this Function? because we already have 'db buffer cache' if the only thing we do is to query tables.
    Many thanks.

    Hi Morven,
    As of now, PL/SQL Result cache feature is only enabled for stored functions and not for procedures. This is due to the objectives they achieve. Functions are usually computative and procedures are for logic implementation.
    And for enabling result caching feature for a function, you are the better judge as u can test the performance in both the case. But, i would support enabling the cache because oracle 11g provides Cache as a different SGA component. db_buffer_cache will also be used for buffering other data blocks and not the result sets.
    Hope my explanation is fine.

  • Populating item with pl/sql function body

    Hi,
    I want to populate a "Display as text (saves state)" item with the difference of 2 other items.
    The source of my item is:
    - Only when current...
    - PL/SQL Function body
    - Source expression:
    DECLARE
    v_diff NUMBER;
    BEGIN
    v_diff := :P1_AUFWAND_TOTAL - :P1_AUFWAND_BERECHNET;
    return v_diff;
    END;
    Now I get this error:
    ORA-06502: PL/SQL: numerischer oder Wertefehler: Fehler beim Konvertieren von Zeichen zu Zahl
         Error      ERR-1904 Unable to compute item default: type = Function Body...
    I tried to track down the problem with to_number conversion:
    v_diff := to_number(':P1_AUFWAND_BERECHNET'); or
    v_diff := to_number(':P1_AUFWAND_BERECHNET', '999G999D00');
    What's wrong here? It feels like I'm making a simple mistake...
    Thanks for any help,
    Roger

    Hi Denes,
    Thanks for your help. You were right, item :p1_aufwand_berechnet was not a number.
    I created the problem myself by setting the format to:
    return TO_CHAR(v_aufwand,'999G999G999G999G990D00');
    Now the dilemma is that I want to calculate the numbers, but at the end I want a nice format to display them. This obviously only works with TO_CHAR, see:
    Re: Number format mask of text item is not applied
    Maybe this is to be solved with a seperate process after the calculation, to set the format?
    Cheers,
    Roger

  • PL/SQL FUNCTION VAR VALUE

    Hello everybody.
    a Short question , I need help with this, I have a report based in a SQL Query (PL/SQL function body returning SQL Query) and I need to see the query returned.
    My question ¿How I can see the content of the query that I construct?.
    Any help wellcome.
    Thanks & regards everybody.

    You may compute your query in an item:
    http://htmldb.oracle.com/pls/otn/f?p=31517:99
    http://htmldb.oracle.com/pls/otn/f?p=31517:31
    Look at these examples, they may help you.
    Denes Kubicek

  • Report- Pl/sql function returning sql query parsing page items as text?

    Hi Team,
    I am facing a strange issue .
    I have four page items namely
    1)JOB_CODE
    2)MIN_EXP
    3) MAX_EXP
    4) SOURCES1
    I have a report of the type "Pl/sql function returning sql query"
    declare
    v_sql varchar2(4000);
    begin
    if (:JOB_CODE IS NOT NULL and :MIN_EXP IS NOT NULL and :MAX_EXP IS NOT NULL and :SOURCES1 IS NOT NULL) then
    v_sql:= 'select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where V_REQUIREMENT = :JOB_CODE and v_experience_years >= :MIN_EXP and v_experience_years <= :MAX_EXP and source like ' || '''' || '%'|| ':SOURCES1' || '%' || '''';
    elsif (:JOB_CODE IS NULL and :MIN_EXP IS NOT NULL and :MAX_EXP IS NOT NULL and :SOURCES1 IS NOT NULL) then
    v_sql := 'select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where v_experience_years >= :MIN_EXP and v_experience_years <= :MAX_EXP and source like ' || '''' || '%'|| ':SOURCES1' || '%' || '''';
    elsif (:MIN_EXP IS NULL and :JOB_CODE IS NOT NULL and :MAX_EXP IS NOT NULL and :SOURCES1 IS NOT NULL) then
    v_sql := 'select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where v_experience_years <= :MAX_EXP and V_REQUIREMENT = :JOB_CODE and source like ' || '''' || '%'|| ':SOURCES1' || '%' || '''';
    elsif (:MAX_EXP is null and :JOB_CODE IS NOT NULL and :MIN_EXP IS NOT NULL and :SOURCES1 IS NOT NULL) then
    v_sql := 'select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where V_REQUIREMENT = :JOB_CODE and v_experience_years >= :MIN_EXP and source like ' || '''' || '%'|| ':SOURCES1' || '%' || '''';
    end if;
    insert into query_list values (v_sql);
    insert into debug values (:JOB_CODE , :MIN_EXP , :MAX_EXP , :SOURCES1);
    return v_sql;
    end;
    Please not that I am insertin the query into a table called Query_list and the page item values into the table called Debug thru the pl/sql function which returns teh query.
    Now I select the data from the debug tables.
    select unique(query) from query_list;
    select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where V_REQUIREMENT = :JOB_CODE and v_experience_years >= :MIN_EXP and v_experience_years <= :MAX_EXP and source like '%:SOURCES1%'
    select * from debug;
    JOBCODE     MINEX     MAXEX     SOURCE
    21     1     10     donkeyHire
    And if I run the query in sql I get some records returned
    select v_candidate_id, v_fname,v_current_employer,v_Experience_years from candidature where V_REQUIREMENT = 21 and v_experience_years >= 1 and v_experience_years <= and source like 'donkeyHire'
    V_CANDIDATE_ID     V_FNAME     V_CURRENT_EMPLOYER     V_EXPERIENCE_YEARS
    2     Vengu     Andale Tech     4
    But the record does not show up in the report!
    does this type of report parse page items as text?
    Why is it so?
    Waiting for an early reply.
    Thanks,
    venkat

    Venkat - You don't want to put ':SOURCES1' in quotes like that.
    Scott

  • Passing Multiple Values from a worksheet to PL/SQL function.

    Hi All,
    Is there any way to pass multiple values selected in a worksheet to a PL/SQL function ?
    I will try to explain the scenario:
    We have a crosstab report that showing all the customer details, deposit sum of a customer in each date in a date range selected. With the customer details we are showing the Rank of a customer based on the deposit in the latest date selected. Filtering is based on the rank, ie Top50 or Top60 etc.( As I said rank is calculating based on the deposit in the latest date).This is working fine.
    Now the new requirement is to : For example, in Top50 report, list all the customers, who were in the Top50 list, in any of the dates selected. We are able to display the daywise rank, but when giving a condition like daywiserank <= 50, the result becomes uncertain. Some blank lines, wrong amounts etc..
    As a work around we tried to find out the rank in a PL/SQL function. But the issue there is : we have some multiple value parameters used in the worksheet.
    Is there any way to pass multiple values selected in a worksheet to a PL/SQL function ?
    Or any other work arounds for the scenario explained?
    Reagrds,
    Jeneesh

    Hi Russ,
    Thanks for the response.
    Russ Proudman wrote:
    1. I thought there was an analytical function similar to rank - or maybe an option of rank - that if there are duplicate records to have them all considered the same rank. So if you had 3 records all the same as rank=2 then a condition saying where rank=2 would return the 3 records. You could check into this.
    We are already using DENSE_RANK. But the issue is the output contains incorrect null values nd repeated rows.
    We got it solved as I explained in the previous post. But will that AGGREGATION MODE setting ( Which discoverer says - not recommended) have any issue? I mean side effects?
    Russ Proudman wrote:
    2. Another thought is that you can create a PL/SQL routine - that's called from a SQL function registered in Discoverer - where a table is created that does the first part of your query. Then a worksheet is created to use the data from that table. So, in essence, the table would have your top50 ranked customers. Then you can write any kind of worksheet against that table. However, DBAs are loath to allow tables - that they didn't create! - many times in a PROD environment.
    Here also the same problem will occur: as the top 50 will depend upon the parameters. I cannot pass those parameters to PL/SQL Function.And storing the top50 ( itmay be top100 or to 150 also) for all combinations of the parameters is impossible
    Russ Proudman wrote:
    3. Finally, are you sure you're rank function is correct in that if you're getting blank lines, maybe the 'over' part is not considering all columns needed to determine the rank?
    Yes the query we are using is correct. The output QUERY of discoverer gives correct results in Sqlplus.
    Regards,
    Jeneesh

  • Show refcursor returned by a PL/SQL function ?

    Is it possible to show the results returned by a
    PL/SQL function that returns a refcursor ?
    In sqlplus it goes like this:
    SQL> variable a refcursor;
    SQL> execute :a := p_front.get_invoice_list;
    PL/SQL procedure successfully completed.
    SQL> print a;
    INVOICE_ID CLIENT_ID INVOICE_D
    101 100 01-APR-06
    100 100 06-APR-06
    If not, this would be on the top of my wishlist...
    By the way: you did a good job on this tool!
    Regards,
    Willem

    Is it possible to show the results returned by a
    PL/SQL function that returns a refcursor ?
    In sqlplus it goes like this:
    SQL> variable a refcursor;
    SQL> execute :a := p_front.get_invoice_list;
    PL/SQL procedure successfully completed.
    SQL> print a;
    INVOICE_ID CLIENT_ID INVOICE_D
    101 100 01-APR-06
    100 100 06-APR-06
    If not, this would be on the top of my wishlist...
    By the way: you did a good job on this tool!
    Regards,
    Willem

  • Application Report Missing PL/SQL Functional Area

    All,
    I just wanted to bring to the ApEx developers something I just noticed... I use the Shared Components > Database Object Dependencies report to make sure all is well before moving applications into production.
    The Parsing Errors feature of that report is WONDERFUL! But it seems to be overlooking buttons that use a conditional display based on PL/SQL Function Body Returning a Boolean.
    Dan

    Hi Dan,
    I think the place is perfect, but I read once somewhere that "Bug" or "Bug Report" should be in the subject so that's easier to find for the Oracle guys.
    Patrick
    My APEX Blog: http://inside-apex.blogspot.com
    The ApexLib Framework: http://apexlib.sourceforge.net
    The APEX Builder Plugin: http://sourceforge.net/projects/apexplugin/

  • Interactive report from PL/SQL function

    Hello All,
    i have a pl/sql function that dynamically builds up a sql query and returns it as a varchar2.
    when i create a new report then i can use this function in the report like
    return f_function(param1,param2,v('APP_ID'), v('APP_SESSION'));
    and this works fine.
    Except i cannot create an interactive report for this function, because it is not allowed !!!!
    So how can i use the function in an interactive report ?
    Thanks in advance,
    Marco

    Marco,
    Another rather extreme approach would be to go all the way and make your function pipelined (that is not only build but also execute the query) and then select from it in your interactive report.
    The disadvantage here would be that any supplementary filtering would act on the result set of the function (not as an addition to the where clause of the original query). But if you can live with that...
    The advantage would be that there's less fiddling with column headers.
    Regards,
    Iulian

  • Interactive Report with PL/SQL Function Source

    Is it possible to create interactive report with PL/SQL function source returing a query? If not, has anyone done any work to simulate the interactive reporting feature for a normal report using API?

    I haven't tried that before but you could:
    1. create a collection from your result set returned by a dynamic query,
    2. create a view on that collection,
    3. use the view in your interactive report.
    The usability of this proposal depends from a question how "dynamic" your query is - does it always have the same number of columns or not.
    Denes Kubicek
    http://deneskubicek.blogspot.com/
    http://www.opal-consulting.de/training
    http://apex.oracle.com/pls/otn/f?p=31517:1
    -------------------------------------------------------------------

Maybe you are looking for

  • Clear form after CREATING record

    Right now when I fill out a form then click the CREATE button, the record shows up in the report but it also remains in the form in "edit"mode. What I want is after I click the CREATE button, the form clears and the CREATE button remains so I can add

  • Problem with output formatting.

    Hi all, I have an output as shown below. R1             R2                            R3                            R4           R5           R6            R7 20000001      27.02.2007     3326          180080     D4           20000001     27.02.2007 

  • Uploading photos from PC to ipad

    I want to upload photos from my PC to my iPad, but can't copy the photos from my PC into iTunes.

  • Windows Server 2008R2 DC VHD backup wont restore new DC

    hello, I have been tearing my hair out on this, what we currently do is we backup the system state of our main DC and upload this to the cloud (Amazon s3) via a piece of software called Cloud berry system state / bare metal addition. the backup is of

  • Sporadic reboots of a Thinkpad T61

    Hello, we have a Lenovo Thinkpad T61 that reboots itself every few days without providing any information in the logs about the reason for this behaviour. I ran the Lenovo pc-doctor and got a failed result for the nvidia gpu with the error code 7082.