SQLPlus Pivot Date Column - sql

I have a query where I need to pivot a field that includes multiple dates. In short, the administereddate column needs to be pivoted to 6 columns with the dates from newest to oldest across the row.
My current effort is as follows
SELECT student_number,
wheninput,
whoinput,
certificatetype,
MAX(CASE
WHEN vaccine_name = 'DTP' THEN
TO_CHAR(administereddate, 'mm/dd/yyyy')
ELSE
''
END) AS "DTP"
FROM
(
SELECT TO_CHAR(administeredDate, 'mm/dd/yyyy') dose_date,
ROW_NUMBER() OVER (PARTITION BY vaccine_name ORDER BY administereddate DESC) dose
FROM ps.pshealthgrade1)
PIVOT(
LISTAGG(dose_date) WITHIN GROUP (ORDER BY dose_date DESC)
FOR dose IN (1 DTP_dose1,
2 DTP_dose2,
3 DTP_dose3,
4 DTP_dose4,
5 DTP_dose5,
6 DTP_dose6)
)
)
WHERE vaccine_name = 'DTP'
GROUP BY student_number,
wheninput,
whoinput,
vaccine_name,
administereddate,
certificatetype
ORDER BY student_number, vaccine_name, administereddate;

You need dynamically detecting the latest six vaccine dates probably to be counted per each day. In order to accomplish this, create such a function firstly ;
CREATE OR REPLACE FUNCTION get_vaccine_rs(
i_vcc ps.pshealthgrade1.vaccine_name%TYPE
) RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_str VARCHAR2(32767);
BEGIN
SELECT LISTAGG( ''''||TO_CHAR(administeredDate, 'mm/dd/yyyy')||''' AS "DTP_dose'||rn||'"' , ',' )
WITHIN GROUP ( ORDER BY rn )
INTO v_str
FROM ( SELECT *
FROM
( SELECT administeredDate, ROW_NUMBER() OVER (ORDER BY administeredDate DESC) AS rn
FROM ( SELECT DISTINCT administeredDate
FROM ps.pshealthgrade1
WHERE vaccine_name = i_vcc )
)
WHERE rn <= 6 );
v_sql :=
'SELECT *
FROM ps.pshealthgrade1
PIVOT
(
COUNT(*) FOR administeredDate IN ( '|| v_str ||' )
)
';
OPEN v_recordset FOR v_sql USING i_vcc;
RETURN v_recordset;
END;
/
Then run the below code :
VAR rc REFCURSOR
EXEC :rc := get_vaccine_rs('DTP');
PRINT rc
from SQL Developer's Command Line in order to see the result set.

Related

Need PL/SQL stored procedure to convert column into rows

I have table as -
filename description value
-------- ------------------------------------------ --------------------
rec_123 PropertyWriteCount_rows_0_month February 2018
rec_123 rows_PropertyWriteCount_rows_0_description property write count
rec_123 PropertyWriteCount_rows_0_value_value 1234
rec_123 PropertyWriteCount_rows_0_value_baseType LONG
I want to convert it into -
filename month value description value_basetype
-------- ------------- ----- ------------------------- --------------
rec_2134 February 2018 1234 PropertyWriteCount_rows_0 long
I could able to write PL/SQL till this point, need help for next steps -
CREATE PROCEDURE rows_column IS
CURSOR get_rows IS
SELECT * FROM table1 where description LIKE 'PropertyWriteCount_rows%';
BEGIN
DBMS_OUTPUT.PUT_LINE('table info -');
END;
/
You can do this with conditional aggregation:
select
filename,
max(case when description = 'PropertyWriteCount_rows_0_month' then value end) as month,
max(case when description = 'rows_PropertyWriteCount_rows_0_description' then value end) as description,
max(case when description = 'PropertyWriteCount_rows_0_value_value' then value end) as value,
max(case when description = 'PropertyWriteCount_rows_0_value_baseType' then value end) as value_basetype
from table1
where description like '%PropertyWriteCount_rows%'
group by filename
You can use PIVOT clause after rendering description column in order to extract the last word after last underscore from that column.
The following query might be used as a static approach
SELECT *
FROM
(
SELECT REGEXP_SUBSTR(description,'[^_]+$') AS title,
filename, value
FROM table1 )
PIVOT
(
MAX(value) FOR title IN ('month' AS month, 'value' AS value,
'description' AS description, 'baseType' AS baseType)
)
Demo
but a dynamic approach should be preferred rather, through creating a stored function as in the following PL/SQL code
CREATE OR REPLACE FUNCTION Get_File_Values RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_col VARCHAR2(32767);
BEGIN
SELECT LISTAGG( ''''||titles||''' AS '||titles , ',' )
WITHIN GROUP ( ORDER BY titles DESC )
INTO v_col
FROM ( SELECT DISTINCT REGEXP_SUBSTR(description,'[^_]+$') AS titles
FROM table1 );
v_sql :=
'SELECT *
FROM (
SELECT REGEXP_SUBSTR(description,''[^_]+$'') AS title,
filename, value
FROM table1
)
PIVOT
(
MAX(value) FOR title IN ( '|| v_col ||' )
)';
OPEN v_recordset FOR v_sql;
DBMS_OUTPUT.PUT_LINE(v_sql);
RETURN v_recordset;
END;
/
Then running the below code :
VAR rc REFCURSOR
EXEC :rc := Get_File_Values;
PRINT rc
from SQL Developer's Command Line
or
BEGIN
:result := Get_File_Values;
END;
from Test window of PL/SQL Developer (as tagged)
in order to see the expected result set varying even if the new values for description column are inserted or some former values are deleted.

how transpose a table using two columns

i need help to transpose a table but just using one column and replicate information from another column.
UPDATE
I have this query:
CREATE SEQUENCE SEQ_document MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 2206 NOCACHE ORDER NOCYCLE NOKEEP NOSCALE GLOBAL;
CREATE TABLE ALL_DOCUMENT (
ID NUMBER(19,0) DEFAULT SEQ_document.nextval NOT NULL
,ART_DOC VARCHAR2(256 CHAR)
,TYPE_DOC VARCHAR2(256 BYTE)
,DATE_DOC TIMESTAMP(6)
,VALUE_DOC NUMBER(19,6)
,TABLENAME_DOC VARCHAR2(256 BYTE)
);
INSERT INTO "MIBDES"."ALL_DOCUMENT" (ART_DOC, TYPE_DOC, DATE_DOC, VALUE_DOC, TABLENAME_DOC) VALUES ('A00', '35', TO_TIMESTAMP('2020-04-30 13:49:24.330761000', 'YYYY-MM-DD HH24:MI:SS.FF'), '9,7599', 'table_1');
INSERT INTO "MIBDES"."ALL_DOCUMENT" (ART_DOC, TYPE_DOC, DATE_DOC, VALUE_DOC, TABLENAME_DOC) VALUES ('A00', '75', TO_TIMESTAMP('2020-03-14 13:50:02.312782000', 'YYYY-MM-DD HH24:MI:SS.FF'), '13,6562', 'table_2');
INSERT INTO "MIBDES"."ALL_DOCUMENT" (ART_DOC, TYPE_DOC, DATE_DOC, VALUE_DOC, TABLENAME_DOC) VALUES ('A00', '35', TO_TIMESTAMP('2020-03-4 13:50:02.312782000', 'YYYY-MM-DD HH24:MI:SS.FF'), '6,9978', 'table_2');
INSERT INTO "MIBDES"."ALL_DOCUMENT" (ART_DOC, TYPE_DOC, DATE_DOC, VALUE_DOC, TABLENAME_DOC) VALUES ('A00', '16', TO_TIMESTAMP('2020-04-8 13:50:02.312782000', 'YYYY-MM-DD HH24:MI:SS.FF'), '4,7851', 'table_3');
commit;
The idea or requirement is get this:
And i don't have a clear idea how to make this transpose. Can somebody give me a hand?
Best Regards
Do the columns table_1 and table_2 display the same value in all rows?
The following subquery to use CASE expression and MAX function can get one row.
Then you can get your expected result by joining the row and ALL_DOCUMENT table.
SELECT ART_DOC,TYPE_DOC,DATE_DOC,"table_1","table_2"
FROM ALL_DOCUMENT CROSS JOIN
(SELECT
MAX(CASE WHEN TABLENAME_DOC='table_1' THEN VALUE_DOC END) AS "table_1",
MAX(CASE WHEN TABLENAME_DOC='table_2' THEN VALUE_DOC END) AS "table_2"
FROM ALL_DOCUMENT) T;
dbfiddle
In case of your updated question, the query is below:
SELECT ART_DOC,TYPE_DOC,
MAX(CASE WHEN TABLENAME_DOC='table_1' THEN VALUE_DOC END) AS "table_1",
MAX(CASE WHEN TABLENAME_DOC='table_2' THEN VALUE_DOC END) AS "table_2",
MAX(CASE WHEN TABLENAME_DOC='table_3' THEN VALUE_DOC END) AS "table_3"
FROM ALL_DOCUMENT
GROUP BY ART_DOC,TYPE_DOC
ORDER BY "table_1","table_2","table_3";
You can get VALUE_DOCs of each TABLENAME_DOC using by GROUP BY clause and MAX function with CASE expression.
dbfiddle
Basically there are two methods for pivoting within Oracle's SQL :
Using Conditional Aggregation :
While you can pivot the resulting columns as
SELECT art_doc, type_doc,
MAX(CASE WHEN tablename_doc = 'table_1' THEN value_doc END) AS "table_1",
MAX(CASE WHEN tablename_doc = 'table_2' THEN value_doc END) AS "table_2",
MAX(CASE WHEN tablename_doc = 'table_3' THEN value_doc END) AS "table_3"
FROM all_document
GROUP BY art_doc, type_doc;
this is the static method, you'd better prefering the dynamic method through creating a function returning value of type SYS_REFCURSOR such as
CREATE OR REPLACE FUNCTION Get_Pivoted_Documents RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_cols VARCHAR2(32767);
BEGIN
SELECT LISTAGG( 'MAX(CASE WHEN tablename_doc = '''||tablename_doc||''' THEN value_doc END) AS "'||tablename_doc||'"' , ',' )
WITHIN GROUP ( ORDER BY TO_NUMBER( REGEXP_REPLACE(tablename_doc,'[^0-9]') ) )
INTO v_cols
FROM (
SELECT DISTINCT tablename_doc
FROM all_document
);
v_sql :=
'SELECT art_doc , type_doc, '|| v_cols ||'
FROM all_document
GROUP BY art_doc , type_doc';
OPEN v_recordset FOR v_sql;
RETURN v_recordset;
END;
/
Using PIVOT Clause :
with static method ;
SELECT art_doc , type_doc,
MAX("table_1") AS "table_1",
MAX("table_2") AS "table_2",
MAX("table_3") AS "table_3"
FROM all_document
PIVOT
(
MAX(value_doc) FOR tablename_doc IN ('table_1' AS "table_1",'table_2' AS "table_2",'table_3' AS "table_3")
)
GROUP BY art_doc , type_doc;
with dynamic method :
CREATE OR REPLACE FUNCTION Get_Pivoted_Documents RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_cols_1 VARCHAR2(32767);
v_cols_2 VARCHAR2(32767);
BEGIN
SELECT LISTAGG( 'MAX("'||tablename_doc||'") AS "'||tablename_doc||'"' , ',' )
WITHIN GROUP ( ORDER BY TO_NUMBER( REGEXP_REPLACE(tablename_doc,'[^0-9]') ) )
INTO v_cols_1
FROM (
SELECT DISTINCT tablename_doc
FROM all_document
);
SELECT LISTAGG( ''''||tablename_doc||''' AS "'||tablename_doc||'"' , ',' )
WITHIN GROUP ( ORDER BY TO_NUMBER( REGEXP_REPLACE(tablename_doc,'[^0-9]') ) )
INTO v_cols_2
FROM (
SELECT DISTINCT tablename_doc
FROM all_document
);
v_sql :=
'SELECT art_doc , type_doc, '|| v_cols_1 ||'
FROM all_document
PIVOT
(
MAX(value_doc) FOR tablename_doc IN ( '|| v_cols_2 ||' )
)
GROUP BY art_doc , type_doc';
OPEN v_recordset FOR v_sql;
RETURN v_recordset;
END;
/
and then revoke from SQL Developer's console as
SQL> DECLARE
result SYS_REFCURSOR;
BEGIN
:result := Get_Pivoted_Documents;
END;
/
SQL> PRINT result ;
or from PL/SQL Developer's Test Window :
begin
-- Call the function
:result := get_pivoted_documents; --> yields Value of type <Cursor>
end;

PL/SQL procedure to output line the given date if not existing, latest date should be given

I have this table informationvalues with the contents:
Now I create a procedure where I need to input a date parameter which should output line the correct attr with given price. If the date doesn't exist the latest date should be selected.
The solution table for to_date('01-jan-19') would look like this:
This would be then output line in the procedure.
Should I select to correct tuple and output line it or would it be best to just bulk collect everything and then check in a for loop with an if statement what tuple I need to display.
What I have so far:
A select statement with the tuples I am looking for:
create or replace procedure print_inf_value(closingDate Date) is
cursor d1 (closingDate Date) is
select t.attr, t.dateOfValue, t.price
from (
select i.*,
row_number() over (
partition by attr
order by case when dateOfValue = closingdate then 1 else 2 end, dateOfValue desc
) rn
from InformationValues i
) t
where t.rn = 1;
BEGIN
dbms_output.put_line('Information Value ');
dbms_output.put_line('--------------------------------');
FOR d1_rec IN d1 LOOP
dbms_output.put_line(d1_rec.attr || ' ' || d1_rec.price );
END LOOP;
END;
Or a procedure where I bulk collect everything and then I need to sort out what tuple I need:
create or replace procedure print_inf_value(closingDate Date) is
TYPE d1 IS TABLE OF informationvalues%rowtype;
emps d1;
begin select * bulk collect into emps
from informationvalues;
FOR i IN 1 .. emps.COUNT LOOP
if emps(i).dateofvalue = closingDate then
dbms_output.put_line(emps(i).attr || ' ' || emps(i).price );
/*else*/
end if;
END LOOP;
END;
Both are not working right, so what am I missing to display tuple with the correct date.
Please try:
CREATE OR REPLACE PROCEDURE print_inf_value (closingDate DATE)
IS
BEGIN
DBMS_OUTPUT.put_line (RPAD ('ATTR', 20) || RPAD ('PRICE', 20));
FOR o
IN (select attr, trim(case when price < 1 then to_char(price,90.9) else to_char(price) end) price from (
select attr, price, dateofvalue,
row_number() over (partition by attr order by dateofvalue desc) rn from informationvalues
) i where dateofvalue = closingdate
or (rn = 1 and not exists (select 1 from informationvalues iv where iv.attr = i.attr and dateofvalue = closingdate) )
)
LOOP
DBMS_OUTPUT.put_line (RPAD (o.attr, 20) || RPAD ( o.price, 20));
END LOOP;
END;
Sample execution:
set serveroutput on;
begin
print_inf_value(date'2019-01-01');
end;
Output:
ATTR PRICE
age 2
electronics 0.5
gender 3
hobbies 0.5
homeAddress 7
maritalStatus 1
mobilePhone 5
musicTaste 0.1
socialContacts 1

using dynamic sql to create column for select statement

I'm writing a stored procedure for paginated results and this result can be ordered by certain values. I did have a switch case in a select statement but because it was trying to do an orderby on rownum it was very slow.
Now I am trying to use dyanmic sql to build the query outside the select but I don't know if what I am doing is possible.
Here is my SQL in Oracle SQL Developer:
create or replace PROCEDURE Sp_tsa_trainees_pagination (
schemeid IN INT,
searchval IN VARCHAR2,
pagesize IN INT DEFAULT 20,
currentpage IN INT DEFAULT 1,
--orderby IN VARCHAR2,
cursor_ OUT SYS_REFCURSOR)
AS
-- LOCAL VARIABLES
totalcount INT;
numberofpages INT;
startposition NUMBER;
endposition NUMBER;
orderby VARCHAR2(100) := 'surname asc' ;
dynamic_query VARCHAR(255) := 'row_number() over (order by t.SURNAME DESC, t.FORENAMES DESC) AS rnum';
BEGIN
-- Get total number of trainees in scheme
select COUNT(t.ORG_REGISTRATION_ID)
into totalcount FROM v_trainee t
where t.ORG_REGISTRATION_ID = schemeid
AND t.status = 'A' and LOWER(t.trainee_name) like '%' || LOWER(searchval) || '%';
-- calculate number of pages in the pagination by dividing total number of records by how many to display for each page
numberofpages := totalcount / pagesize;
-- get start position by multiplying number of records to display for each page by current page
startposition := pagesize *( currentpage-1);
-- add calculated start position by number of records to display to get end position
endposition := startposition + pagesize;
CASE orderby
WHEN 'surname desc' THEN dynamic_query := 'row_number() over (order by t.SURNAME DESC, t.FORENAMES DESC) AS rnum';
WHEN 'surname asc' THEN dynamic_query := 'row_number() over (order by t.SURNAME ASC, t.FORENAMES ASC) AS rnum';
END CASE;
OPEN cursor_ FOR
Select * from
(
SELECT
-- order by based on selection
dynamic_query rnum,
t.ORG_REGISTRATION_ID SearchId,
t.FORENAMES Forenames,
t.FORENAME Forename,
t.SURNAME Surname,
t.person_id PersonId,
t.trainee_name TraineeName,
t.STATUS Status,
t.IPD_ANNUAL_REVIEW_DATE AnnualReviewDate,
t.ANNUAL_REVIEW_STATUS AnnualReviewStatus,
t.payment_received PaymentRecieved,
t.TRAINEE_ID TraineeId,
t.IPD_SIGNUP_DATE IpdSignupDate,
t.START_DATE StartDate,
t.END_DATE EndDate,
t.LENGTH_ON_SCHEME LengthOnScheme,
t.EMPLOYEE_NUMBER EmploymentNumber,
t.SELECTED_LEVEL SelectedLevel,
t.SELECTED_LEVEL_DESCRIPTION SelectedLevelDescription,
t.ELIGIBLE_LEVEL EligibleLevel,
t.ELIGIBLE_LEVEL_DESCRIPTION EligibleLevelDescription,
sce.FORENAMES SceForenames,
sce.FORENAME SceForename,
sce.SURNAME SceSurname,
sce.mentor_name SceName,
sce.EMPLOYEE_NUMBER SceEmployeeNumber,
de.FORENAMES DeForenames,
de.FORENAME DeForename,
de.SURNAME DeSurname,
de.mentor_name DeName,
de.EMPLOYEE_NUMBER DeEmployeeNumber,
t.COMPLETED_ATTRIBUTE_LEVELS CompletedAttributeLevels,
t.ATTRIBUTE_LEVEL_COUNT AttributeLevelCount,
-- get percentage
CASE t.ATTRIBUTE_LEVEL_COUNT
WHEN 0 THEN 0
ELSE
COMPLETED_ATTRIBUTE_LEVELS / t.ATTRIBUTE_LEVEL_COUNT * 100
END percentage,
DECODE(F_ISTRAINEEGROUPMEMBER(t.ORG_REGISTRATION_ID, 'S', t.person_id),'Y','N','Y') WithoutTsaGroup,
orr.status SchemeStatus,
(select count(*) from TRAINING_GROUP_TRAINEE tgt where tgt.trainee_id = t.TRAINEE_ID) NUMBER_OF_GROUPS,
TotalCount
FROM v_trainee t
INNER JOIN org_registration orr ON t.ORG_REGISTRATION_ID = orr.id
LEFT OUTER JOIN v_mentor sce ON t.sce_id = sce.MENTOR_ID
LEFT OUTER JOIN v_mentor de ON t.de_id = de.MENTOR_ID
where t.ORG_REGISTRATION_ID = schemeid AND t.status = 'A'
and LOWER(t.trainee_name) like '%' || LOWER(searchval) || '%'
)
where rnum >= startposition and rnum <= endposition;
END;
I want to use this variable with the assigned sql:
dynamic_query rnum,
But when I execute the stored procedure I get this error:
ORA-01722: invalid number ORA-06512: at
"db.SP_TSA_TRAINEES_PAGINATION", line 46 ORA-06512: at line 13
So basically my question is can I assign a SQL to VARCHAR2 and then use it in a select statement dynamically.
You may need dynamic SQL for this. For example:
create or replace procedure testDyn(n in number, C OUT SYS_REFCURSOR) is
vDynamicPart varchar2(1000);
vSQl varchar2(1000);
begin
--
if (n = 1) then
vDynamicPart := 'count(1)';
else
vDynamicPart := 'count(null)';
end if;
--
vSQl := 'select ' || vDynamicPart || ' from dual';
open C for vSQl;
end;
If you call it
declare
n1 number;
n2 number;
C1 SYS_REFCURSOR;
C2 SYS_REFCURSOR;
begin
testDyn(1, C1);
testDyn(2, C2);
fetch C1 into n1;
fetch C2 into n2;
dbms_output.put_line('n1: ' || n1);
dbms_output.put_line('n2: ' || n2);
end;
you get:
n1: 1
n2: 0

Order by in subquery (for jQuery jTable) doesn't work?

Some background:
My framework jQuery jTable, allows me to do pagination and sort columns, in my select query I need to retrieve n rows (from nth, to nth) and previously order the data by the selected column.
I have a table with n columns where would not exist some rows (this is an example):
To achieve the first requirement I wrote the follow procedure:
create or replace
PROCEDURE PR_SHOWVALUESOLD
(
PRMROWMIN IN NUMBER
, PRMROWMAX IN NUMBER
, CURSORRESULT OUT SYS_REFCURSOR
) AS
BEGIN
open CURSORRESULT for
select * from
(select v.*, rownum r,
(
select count(*) TOTALITEMS from TABLE1 v
) TOTALITEMS
from TABLE1 v
) d
where d.r >= PRMROWMIN and d.r <= PRMROWMAX;
END PR_SHOWVALUESOLD;
This work successfully, I execute the procedure with the follows parameters (PRMROWMIN = 6, PRMROWMAX = 9), the result of the procedure are in Output Varibles window.
Now comes the next step, I need to order the data before take from n to x row.
I rewrite the procedure to do this, but doesn't work:
CREATE OR REPLACE PROCEDURE PR_SHOWVALUES
(
PRMROWMIN IN NUMBER
, PRMROWMAX IN NUMBER
, PRMORDERCOL IN VARCHAR2
, PRMORDERDIR IN VARCHAR2
, CURSORRESULT OUT SYS_REFCURSOR
) AS
BEGIN
open CURSORRESULT for
select * from
(select v.*, rownum r,
(
select count(*) TOTALITEMS from TABLE1 v
) TOTALITEMS
from TABLE1 v
order by 'LOWER(' || PRMORDERCOL || ')' || ' ' || PRMORDERDIR
) d
where d.r >= PRMROWMIN and d.r <= PRMROWMAX;
END PR_SHOWVALUES;
I executed the modified procedure with the follows parameters:
PRMROWMIN := 6;
PRMROWMAX := 9;
PRMORDERCOL := 'COLUMNA';
PRMORDERDIR := 'DESC';
I expected the highlighted rows Query Result 2 window (but this new procedure retrieve the same data as old but disordered Output Variables Window):
How to achieve my requirements?
Thanks in advance.
This is your order by:
order by 'LOWER(' || PRMORDERCOL || ')' || ' ' || PRMORDERDIR
It is not applying the function lower(). Instead, it is concatenating the strings. You may mean:
order by LOWER(PRMORDERCOL) ' ' || PRMORDERDIR
I found a solution to my requirement.
I need to use DECODE to match every column to sort.
I can order in subquery, in this case I do two order by in two subqueries.
The documentation of PL/SQL DECODE function are in:
PL/SQL DECODE FUNCTION
The final Procedure are:
CREATE OR REPLACE PROCEDURE PR_SHOWVALUES
(
PRMROWMIN IN NUMBER
, PRMROWMAX IN NUMBER
, PRMORDERCOL IN VARCHAR2
, PRMORDERDIR IN VARCHAR2
, CURSORRESULT OUT SYS_REFCURSOR
) AS
BEGIN
open CURSORRESULT for
select * from (
select rownum r, v.* from
(
select * from
(
select * from table1 tbl
order by decode
(
UPPER(PRMORDERCOL),
'COLUMNA', LOWER(tbl.COLUMNA),
'COLUMNB', LOWER(tbl.COLUMNB),
LOWER(tbl.TABLE1_ID)
)
)
ORDER BY
CASE
WHEN UPPER(PRMORDERDIR) = 'DESC' THEN
ROWNUM * -1
ELSE
ROWNUM
END
) v
)
where r >= PRMROWMIN and r <= PRMROWMAX;
END PR_SHOWVALUES;
Acknowledgment to Jack David Baucum where I found the solution.