Unpivot Multiple Columns in Oracle SQL - sql

I have a requirement to unpivot a table similar to the table below:
create TABLE dummy_x
(
EMP_NAME VARCHAR2(100)
, EMP_NUMBER VARCHAR2(100)
, PAYROLL_NAME VARCHAR2(100)
, PAYROLL_ID NUMBER
, JOB_TITLE VARCHAR2(100)
, JOB_TITLE_ID NUMBER
, LOCATION VARCHAR2(100)
, LOCATION_ID NUMBER
, NEW_PAYROLL_NAME VARCHAR2(100)
, NEW_PAYROLL_ID NUMBER
, NEW_JOB_TITLE VARCHAR2(100)
, NEW_JOB_TITLE_ID NUMBER
, NEW_LOCATION VARCHAR2(100)
, NEW_LOCATION_ID NUMBER
);
INSERT INTO dummy_x (EMP_NAME, EMP_NUMBER, PAYROLL_NAME, PAYROLL_ID, JOB_TITLE, JOB_TITLE_ID, LOCATION, LOCATION_ID, NEW_PAYROLL_NAME, NEW_PAYROLL_ID, NEW_JOB_TITLE, NEW_JOB_TITLE_ID, NEW_LOCATION, NEW_LOCATION_ID)
VALUES ('MISIP', '111X', 'PAY1', 1, 'DEVELOPER', 2, 'PHIL', 3, 'PAYPHIL', 11, 'PHIL DEV', 22, 'MANILA PH', 33);
INSERT INTO dummy_x (EMP_NAME, EMP_NUMBER, PAYROLL_NAME, PAYROLL_ID, JOB_TITLE, JOB_TITLE_ID, LOCATION, LOCATION_ID, NEW_PAYROLL_NAME, NEW_PAYROLL_ID, NEW_JOB_TITLE, NEW_JOB_TITLE_ID, NEW_LOCATION, NEW_LOCATION_ID)
VALUES ('FHONS', '111Y', 'PAY2', 2, 'SUPPORT', 3, 'HONDURAS', 4, 'PAYHON', 55, 'HON SUP', 66, 'SP SULA HON', 77);
I need the format to be something like below:
EMP_NAME EMP_NUMBER DETAILS CURRENT_VALUE NEW_VALUE
--------- ------------ -------------- -------------- ----------
MISIP 111X PAYROLL_NAME PAY1 PAYPHIL
PAYROLL_ID 1 11
JOB_TITLE DEVELOPER PHIL DEV
JOB_TITLE_ID 2 22
LOCATION PHIL MANILA PH
LOCATION_ID 3 33
FHONS 111Y PAYROLL_NAME PAY2 PAYHON
PAYROLL_ID 2 55
JOB_TITLE SUPPORT HON SUP
JOB_TITLE_ID 3 66
LOCATION HONDURAS SP SULA HON
LOCATION_ID 4 77
This is what i've done so far:
SELECT EMP_NAME
, EMP_NUMBER
, Details
, current_value
FROM (SELECT EMP_NAME
, EMP_NUMBER
, PAYROLL_NAME
, cast(PAYROLL_ID as varchar2(100)) PAYROLL_ID
, JOB_TITLE
, cast(JOB_TITLE_ID as varchar2(100)) JOB_TITLE_ID
, LOCATION
, cast(LOCATION_ID as varchar2(100)) LOCATION_ID
, NEW_PAYROLL_NAME
, cast(NEW_PAYROLL_ID as varchar2(100)) NEW_PAYROLL_ID
, NEW_JOB_TITLE
, cast(NEW_JOB_TITLE_ID as varchar2(100)) NEW_JOB_TITLE_ID
, NEW_LOCATION
, cast(NEW_LOCATION_ID as varchar2(100)) NEW_LOCATION_ID
FROM dummy_x)
unpivot (current_value for Details in (PAYROLL_NAME
, PAYROLL_ID
, JOB_TITLE
, JOB_TITLE_ID
, LOCATION
, LOCATION_ID));
QUERY OUTPUT
EMP_NAME EMP_NUMBER DETAILS CURRENT_VALUE NEW_VALUE
--------- ------------ -------------- -------------- ----------
MISIP 111X PAYROLL_NAME PAY1
MISIP 111X PAYROLL_ID 1
MISIP 111X JOB_TITLE DEVELOPER
MISIP 111X JOB_TITLE_ID 2
MISIP 111X LOCATION PHIL
MISIP 111X LOCATION_ID 3
FHONS 111Y PAYROLL_NAME PAY2
FHONS 111Y PAYROLL_ID 2
FHONS 111Y JOB_TITLE SUPPORT
FHONS 111Y JOB_TITLE_ID 3
FHONS 111Y LOCATION HONDURAS
FHONS 111Y LOCATION_ID 4
How can i add the "New Value" Column data to this script and would it be possible to remove the duplicate data from the EMP_NAME and EMP_NUMBER columns?

To get both columns is much easier than you may think: unpivot ( (current_value, new_value) for details in...) Of course, the "details" should also be given in pairs, each enclosed in ( ... , ... ). For example: for ((payroll_name, new_payroll_name) as 'PAYROLL NAME', .... )
The second requirement doesn't make sense. Which row should keep the EMP_NAME and the EMP_NUMBER, and which should show NULL? What if the row you "think" should get the values doesn't actually exist, or must be deleted in further processing? THAT is something you should do in your front-end application (for example in SQL*Plus, where what you want is easy to do).

Do the cell merging in your application code.
For new_value, try this:
SELECT EMP_NAME
, EMP_NUMBER
, Details
, current_value
, new_value
FROM (SELECT EMP_NAME
, EMP_NUMBER
, PAYROLL_NAME
, cast(PAYROLL_ID as varchar2(100)) PAYROLL_ID
, JOB_TITLE
, cast(JOB_TITLE_ID as varchar2(100)) JOB_TITLE_ID
, LOCATION
, cast(LOCATION_ID as varchar2(100)) LOCATION_ID
, NEW_PAYROLL_NAME
, cast(NEW_PAYROLL_ID as varchar2(100)) NEW_PAYROLL_ID
, NEW_JOB_TITLE
, cast(NEW_JOB_TITLE_ID as varchar2(100)) NEW_JOB_TITLE_ID
, NEW_LOCATION
, cast(NEW_LOCATION_ID as varchar2(100)) NEW_LOCATION_ID
FROM dummy_x)
unpivot ((current_value, new_value) for Details in (
(PAYROLL_NAME, NEW_PAYROLL_NAME) as 'PAYROLL_NAME'
, (PAYROLL_ID , NEW_PAYROLL_ID ) as 'PAYROLL_ID'
, (JOB_TITLE , NEW_JOB_TITLE ) as 'JOB_TITLE'
, (JOB_TITLE_ID, NEW_JOB_TITLE_ID) as 'JOB_TITLE_ID'
, (LOCATION , NEW_LOCATION ) as 'LOCATION'
, (LOCATION_ID , NEW_LOCATION_ID) as 'LOCATION_ID'
)
);

Related

Select and insert on the same table

Can you tell me what is wrong with this query:
INSERT INTO properties 
(
f_gen_id(NULL)
, 'ASHAgroup18E'
, entity
, effective_dt
, property_key
, property_value
, created_by
, create_ts
, updated_by
, update_ts
) 
SELECT f_gen_id(NULL)
, 'ASHAgroup18E'
, entity
, effective_dt
, property_key
, property_value
, description
, created_by
, create_ts
, updated_by
, update_ts
-- 'UIL-Migration', CURRENT_TIMESTAMP, 'UIL-Migration', CURRENT_TIMESTAMP 
FROM properties
WHERE group_key = 'ASHAgroup18B';
In the INSERT part you should have column names, not a function
INSERT INTO properties (f_gen_id(NULL),...
replace this with the name of the primary key/id column
INSERT INTO properties (id,...
Update
I guess also the second column in the INSERT is incorrect since it contains a string. Again, replace it with a column name

I've been trying to insert a specific data to my database

I have been trying to insert a data into my database, but it seems am missing a comma , and i have tried to figure out where , but i cant seems to find the issue, any help would be appreciated... newbie here..
thanks
INSERT INTO EMPLOYEES
( FIRST_NAME ,
LAST_NAME ,
EMAIL ,
PHONE_NUMBER ,
HIRE_DATE ,
JOB_ID ,
Salary ,
COMMISSION_PCT ,
MANAGER_ID ,
DEPARTMENT_ID )
VALUES (
'Jackson' ,
'Kayode' ,
'amima#gmail#gmail.com',
216.313.9890 ,
12-12-18 ,
'AD_PRES' ,
10500 ,
0.10 ,
100 ,
90 );
You need single quotes around date constants and strings. I would recommend using the date keyword:
INSERT INTO EMPLOYEES (FIRST_NAME , LAST_NAME , EMAIL , PHONE_NUMBER , HIRE_DATE , JOB_ID , Salary , COMMISSION_PCT , MANAGER_ID , DEPARTMENT_ID)
VALUES ('Jackson', 'Kayode', 'amima#gmail#gmail.com', '216.313.9890',
date '2018-12-12', 'AD_PRES', 10500, 0.10, 100, 90
);

How to create an Oracle audit trigger?

CREATE OR REPLACE TRIGGER EVALUATION
BEFORE INSERT OR UPDATE OR DELETE ON BOOKING
FOR EACH ROW
DECLARE
BEGIN
SELECT BOOKING_EVALUATION FROM BOOKING WHERE BOOKING_EVALUATION > 2;
SELECT BOOKING_EVALUATION INTO EVALUATIONAUDIT FROM BOOKING;
IF INSERTING THEN
INSERT INTO EVALUATIONAUDIT (VOYAGES_ID,CUSTOMER_NAME,START_DATE,SHIP_NAME,BOOKING_EVALUATION)
VALUES(:NEW.VOYAGES_ID,:NEW.CUSTOMER_NAME,:NEW.START_DATE,:NEW.SHIP_NAME,:NEW.BOOKING_EVALUATION);
END IF;
IF UPDATING THEN
INSERT INTO EVALUATIONAUDIT (VOYAGES_ID,CUSTOMER_NAME,START_DATE,SHIP_NAME,BOOKING_EVALUATION)
VALUES(:OLD.VOYAGES_ID,:OLD.CUSTOMER_NAME,:OLD.START_DATE,:OLD.SHIP_NAME,:OLD.BOOKING_EVALUATION);
END IF;
IF DELETING THEN
INSERT INTO EVALUATIONAUDIT (VOYAGES_ID,CUSTOMER_NAME,START_DATE,SHIP_NAME,BOOKING_EVALUATION)
VALUES(:OLD.VOYAGES_ID,:OLD.CUSTOMER_NAME,:OLD.START_DATE,:OLD.SHIP_NAME,:OLD.BOOKING_EVALUATION);
END IF;
END;
This is my audit table:
desc evaluationaudit;
Name Null? Type
----------------------------------------- -------- -----------------------
AUDITT_ID NOT NULL NUMBER(10)
VOYAGES_ID NOT NULL NUMBER(10)
CUSTOMER_NAME NOT NULL VARCHAR2(20)
START_DATE NOT NULL DATE
SHIP_NAME NOT NULL VARCHAR2(20)
BOOKING_EVALUATION NOT NULL NUMBER(20)
and this is my show error output:
SQL> SHOW ERRORS;
Errors for TRIGGER EVALUATION:
LINE/COL ERROR
-------- -------------------------------------------------------------
12/24 PLS-00049: bad bind variable 'NEW.CUSTOMER_NAME'
12/43 PLS-00049: bad bind variable 'NEW.START_DATE'
12/59 PLS-00049: bad bind variable 'NEW.SHIP_NAME'
18/24 PLS-00049: bad bind variable 'OLD.CUSTOMER_NAME'
18/43 PLS-00049: bad bind variable 'OLD.START_DATE'
18/59 PLS-00049: bad bind variable 'OLD.SHIP_NAME'
24/24 PLS-00049: bad bind variable 'OLD.CUSTOMER_NAME'
24/43 PLS-00049: bad bind variable 'OLD.START_DATE'
24/59 PLS-00049: bad bind variable 'OLD.SHIP_NAME'
I wanted to add to the audit table. If a customer gives a poor evaluation of 2 or less, the details of their voyage (customer_name, name and date of the cruise, ship name and evaluation) but I'm getting error
Warning: Trigger created with compilation errors.
And the audit table is empty, showing no rows selected. I can't seem to find the problem where I am going wrong.
Maybe the following code snippets will help you. Suppose we have 2 tables: BOOKING, and EVALUATION_AUDIT (everything written in uppercase letters is taken from the code in your question).
Tables
create table booking (
VOYAGES_ID number primary key
, CUSTOMER_NAME VARCHAR2(20) NOT NULL
, START_DATE DATE NOT NULL
, SHIP_NAME VARCHAR2(20) NOT NULL
, BOOKING_EVALUATION NUMBER(20) NOT NULL
) ;
create table evaluationaudit (
AUDITT_ID number generated always as identity start with 5000 primary key
, trg_cond_pred varchar2( 64 ) default 'Row not added by evaluation trigger!'
, VOYAGES_ID NUMBER(10) NOT NULL
, CUSTOMER_NAME VARCHAR2(20) NOT NULL
, START_DATE DATE NOT NULL
, SHIP_NAME VARCHAR2(20) NOT NULL
, BOOKING_EVALUATION NUMBER(20) NOT NULL
) ;
Trigger
-- "updating" and "deleting" code omitted for clarity
CREATE OR REPLACE TRIGGER EVALUATION_trigger
BEFORE INSERT OR UPDATE OR DELETE ON BOOKING
FOR EACH ROW
BEGIN
case
when INSERTING then
if :new.booking_evaluation <= 2 then
INSERT INTO EVALUATIONAUDIT
( trg_cond_pred,
VOYAGES_ID, CUSTOMER_NAME, START_DATE, SHIP_NAME, BOOKING_EVALUATION )
VALUES (
'INSERTING'
, :NEW.VOYAGES_ID
, :NEW.CUSTOMER_NAME
, :NEW.START_DATE
, :NEW.SHIP_NAME
, :NEW.BOOKING_EVALUATION
);
end if ;
end case ;
END ;
/
Testing
One of your requirements (in your question) is:
I wanted to add to the audit table. If a customer gives a poor
evaluation of 2 or less, the details of their voyage (customer_name,
name and date of the cruise, ship name and evaluation)
delete from evaluationaudit ;
delete from booking ;
-- booking_evaluation greater than 2 -> no entry in audit table
insert into booking
( VOYAGES_ID, CUSTOMER_NAME, START_DATE, SHIP_NAME, BOOKING_EVALUATION )
values ( 1111, 'customer1', date '2018-05-24', 'ship1', 9999 ) ;
select * from evaluationaudit ;
-- no rows selected
-- booking_evalution = 2 -> insert a row into the audit table
insert into booking
( VOYAGES_ID, CUSTOMER_NAME, START_DATE, SHIP_NAME, BOOKING_EVALUATION )
values ( 1112, 'customer1', date '2018-05-24', 'ship1', 2 ) ;
select * from evaluationaudit ;
AUDITT_ID TRG_COND_PRED VOYAGES_ID CUSTOMER_NAME START_DATE SHIP_NAME BOOKING_EVALUATION
5000 INSERTING 1112 customer1 24-MAY-18 ship1 2
__Update__
If - as you wrote in your comment - you need to pull in some more data from other tables, maybe you want to try the following approach: keep the trigger code rather brief, and use it to call a procedure for the more complicated stuff eg
Tables
create table evaluationaudit (
AUDITT_ID number generated always as identity start with 7000 primary key
, trg_cond_pred varchar2( 64 ) default 'Row not added by evaluation trigger!'
, VOYAGES_ID NUMBER NOT NULL
, CUSTOMER_NAME VARCHAR2(20) NOT NULL
, SHIP_NAME VARCHAR2(20) NOT NULL
, BOOKING_EVALUATION NUMBER(20) NOT NULL
) ;
create table ships ( name varchar2( 64 ), id number unique ) ;
create table customers ( name varchar2( 64 ), id number unique ) ;
insert into ships ( name, id ) values ( 'ship1', 501 );
insert into ships ( name, id ) values ( 'ship2', 502 );
insert into ships ( name, id ) values ( 'ship3', 503 );
insert into customers ( name, id ) values ( 'customer1', 771 ) ;
insert into customers ( name, id ) values ( 'customer2', 772 ) ;
insert into customers ( name, id ) values ( 'customer3', 773 ) ;
create table bookings (
id number generated always as identity start with 5000 primary key
, voyagesid number
, shipid number
, customerid number
, evaluation number
, bookingdate date
);
Trigger
create or replace trigger bookingeval
before insert on bookings
for each row
when ( new.evaluation <= 2 ) -- Use NEW without colon here! ( see documentation )
begin
auditproc( :new.voyagesid, :new.customerid, :new.shipid, :new.evaluation ) ;
end ;
/
Procedure
create or replace procedure auditproc (
voyagesid_ number
, customerid_ number
, shipid_ number
, evaluation_ number
)
as
customername varchar2( 64 ) := '' ;
shipname varchar2( 64 ) := '' ;
begin
-- need to find the customername and shipname before INSERT
select name into customername from customers where id = customerid_ ;
select name into shipname from ships where id = shipid_ ;
insert into evaluationaudit
( trg_cond_pred,
voyages_id, customer_name, ship_name, booking_evaluation )
values (
'INSERTING'
, voyagesid_
, customername
, shipname
, evaluation_
);
end ;
/
Testing
-- evaluation > 2 -> no INSERT into evaluationaudit
insert into bookings
( voyagesid, customerid, shipid, evaluation, bookingdate )
values ( 1111, 771, 501, 9999, sysdate ) ;
select * from evaluationaudit ;
-- no rows selected
-- evaluation = 2
-- -> trigger calling audit procedure -> inserts into evaluationaudit
insert into bookings
( voyagesid, customerid, shipid, evaluation, bookingdate )
values ( 1112, 772, 502, 2, sysdate ) ;
select * from evaluationaudit ;
AUDITT_ID TRG_COND_PRED VOYAGES_ID CUSTOMER_NAME SHIP_NAME BOOKING_EVALUATION
7000 INSERTING 1112 customer2 ship2 2

SQL Query related to maximum job period

I am having a table with four columns namely, eid,ename,hire_date and end_date. Now I want to write a query displaying the name and id of the employee who has worked for the maximum days and the no. of days for which he/she has worked. I have tried a lot but unfortunately I am not getting the desired answer.
Hth..
CREATE TABLE tests
(eid int,ename VARCHAR(20),hire_date DATETIME , end_date Datetime)
INSERT INTO dbo.tests
( eid ,
ename ,
hire_date ,
end_date
)
VALUES ( 1 , -- eid - int
'A1' , -- ename - varchar(20)
'2015-01-03 10:41:43' , -- hire_date - datetime
'2015-03-03 10:41:43' -- end_date - datetime
),
( 2 , -- eid - int
'A2' , -- ename - varchar(20)
'2015-05-03 10:41:43' , -- hire_date - datetime
'2015-06-03 10:41:43' -- end_date - datetime
)
SELECT TOP 1 eid,ename,DATEDIFF(DAY,hire_date,end_date) AS DaysWORKED FROM tests ORDER BY DATEDIFF(DAY,hire_date,end_date) desc
Thanks

Oracle XPath: Parent Node Attribute?

I'm an XPath newbie; I've found a way to do what I want, but wonder if there's another way that can save me some repetition in my code.
I have this table:
CREATE TABLE t (
quark_p1 VARCHAR2(4)
, quark_p2 VARCHAR2(7)
, quark_p3 VARCHAR2(6)
, one VARCHAR2(1)
, two VARCHAR2(1)
, three VARCHAR2(1)
, four VARCHAR2(1)
, five VARCHAR2(1)
, six VARCHAR2(1)
, seven VARCHAR2(1)
, eight VARCHAR2(1)
, nine VARCHAR2(1)
)
;
The following PL/SQL anonymous block does what I want, extracting into this table the structure from my given XML:
BEGIN
INSERT INTO t (
quark_p1
, quark_p2
, quark_p3
, one
, two
, three
, four
, five
, six
, seven
, eight
, nine
)
SELECT x.quark_p1
, x.quark_p2
, x.quark_p3
, x.one
, x.two
, x.three
, x.four
, x.five
, x.six
, x.seven
, x.eight
, x.nine
FROM XMLTABLE('/BASIS/QUARK'
PASSING XMLTYPE (
'<BASIS>
<QUARK P1="up" P2="charm" P3="bottom">
<NEST>
<ONE>A</ONE>
<TWO>B</TWO>
<THREE>C</THREE>
<FOUR>D</FOUR>
<FIVE>E</FIVE>
<SIX>F</SIX>
<SEVEN>G</SEVEN>
<EIGHT>H</EIGHT>
<NINE>I</NINE>
</NEST>
</QUARK>
<QUARK P1="up" P2="strange" P3="top">
<NEST>
<ONE>J</ONE>
<TWO>K</TWO>
<THREE>L</THREE>
<FOUR>M</FOUR>
<FIVE>N</FIVE>
<SIX>O</SIX>
<SEVEN>P</SEVEN>
<EIGHT>Q</EIGHT>
<NINE>R</NINE>
</NEST>
</QUARK>
</BASIS>')
COLUMNS quark_p1 VARCHAR2(4) PATH '#P1'
, quark_p2 VARCHAR2(7) PATH '#P2'
, quark_p3 VARCHAR2(6) PATH '#P3'
, one VARCHAR2(1) PATH 'NEST/ONE'
, two VARCHAR2(1) PATH 'NEST/TWO'
, three VARCHAR2(1) PATH 'NEST/THREE'
, four VARCHAR2(1) PATH 'NEST/FOUR'
, five VARCHAR2(1) PATH 'NEST/FIVE'
, six VARCHAR2(1) PATH 'NEST/SIX'
, seven VARCHAR2(1) PATH 'NEST/SEVEN'
, eight VARCHAR2(1) PATH 'NEST/EIGHT'
, nine VARCHAR2(1) PATH 'NEST/NINE'
) x;
END;
/
This results in the following, which is what I'm after:
SQL> SELECT * FROM t
2 ;
QUARK_P1 QUARK_P2 QUARK_P3 O T T F F S S E N
-------- -------- -------- - - - - - - - - -
up charm bottom A B C D E F G H I
up strange top J K L M N O P Q R
SQL>
Since the "NEST" level is repeated so often, I'd like to pull it up into the starting node, and still get the same results. I'm looking to do something like the following:
BEGIN
INSERT INTO t (
quark_p1
, quark_p2
, quark_p3
, one
, two
, three
, four
, five
, six
, seven
, eight
, nine
)
SELECT x.quark_p1
, x.quark_p2
, x.quark_p3
, x.one
, x.two
, x.three
, x.four
, x.five
, x.six
, x.seven
, x.eight
, x.nine
-- Notice, I changed the starting node from /BASIS/QUARK to /BASIS/QUARK/NEST....
FROM XMLTABLE('/BASIS/QUARK/NEST'
PASSING XMLTYPE (
'<BASIS>
<QUARK P1="up" P2="charm" P3="bottom">
<NEST>
<ONE>A</ONE>
<TWO>B</TWO>
<THREE>C</THREE>
<FOUR>D</FOUR>
<FIVE>E</FIVE>
<SIX>F</SIX>
<SEVEN>G</SEVEN>
<EIGHT>H</EIGHT>
<NINE>I</NINE>
</NEST>
</QUARK>
<QUARK P1="up" P2="strange" P3="top">
<NEST>
<ONE>J</ONE>
<TWO>K</TWO>
<THREE>L</THREE>
<FOUR>M</FOUR>
<FIVE>N</FIVE>
<SIX>O</SIX>
<SEVEN>P</SEVEN>
<EIGHT>Q</EIGHT>
<NINE>R</NINE>
</NEST>
</QUARK>
</BASIS>')
-- ...and I changed all the paths here
COLUMNS quark_p1 VARCHAR2(4) PATH '../#P1'
, quark_p2 VARCHAR2(7) PATH '../#P2'
, quark_p3 VARCHAR2(6) PATH '../#P3'
, one VARCHAR2(1) PATH 'ONE'
, two VARCHAR2(1) PATH 'TWO'
, three VARCHAR2(1) PATH 'THREE'
, four VARCHAR2(1) PATH 'FOUR'
, five VARCHAR2(1) PATH 'FIVE'
, six VARCHAR2(1) PATH 'SIX'
, seven VARCHAR2(1) PATH 'SEVEN'
, eight VARCHAR2(1) PATH 'EIGHT'
, nine VARCHAR2(1) PATH 'NINE'
) x;
END;
/
This seems to me like it should work, but I get this error:
FROM XMLTABLE('/BASIS/QUARK/NEST'
*
ERROR at line 28:
ORA-06550: line 28, column 10:
PL/SQL: ORA-19110: unsupported XQuery expression
ORA-06550: line 2, column 5:
PL/SQL: SQL Statement ignored
SQL>
Am I missing something simple, or can I not get there from here?
Thanks.
I was surprised to find from
How to get the name of the parent element in an Oracle XPath expression?
that it works if you just put "./" in front of the "../"