I'm using Oracle 21C. I have a query that select from 3 tables and works fine with "hard-coded" dates.
Select * from
( Select
vc.last_name
, vc.first_name
, va.attendance_type
, ve.event_date
From
VOL_CONTACT vc
, VOL_ATTENDANCE va
, VOL_EVENT ve
Where
va.contact_fkey = vc.prim_key
And va.event_fkey = ve.prim_key
)
pivot
( max(attendance_type)
for event_date in ('30-mar-2023','18-apr-2023')
)
However, The dates need to be dynamic. I tried to use PIVOT XML with a sub-query. The last four lines were changed to:
pivot xml
( max(attendance_type)
for event_date in (select distinct to_char(event_date, 'dd-mon-yy') from vol_event)
)
. They show the LAST_NAME and FIRST_NAME values fine. However the column heading of the third column is "EVENT_DATE_XML" and the value of that column for every row is "(XMLTYPE)". How do I make PIVOT XML work with a sub-query?
Based on input from a more experienced developer, I went with another approach. Using an Apex Standard Report, I used the following for the report Region/Source (Type=Function Body Returning PL/SQL)
declare
l_pivot_cols varchar2(4000);
l_sql clob := q'{
select
*
from
(select
vc.last_name
, va.attendance_type
, ve.event_date
from
vol_attendance va
full outer join vol_event ve
on va.event_fkey = ve.prim_key
full outer join vol_contact vc
on va.contact_fkey = vc.prim_key
full outer join vol_contact_ministry vcm
on vcm.contact_fkey = vc.prim_key
full outer join vol_ministry vm
on vm.prim_key = vcm.ministry_fkey
where
vm.ministry = 'Refugee'
and vc.status = 'Active'
)
pivot (
max(attendance_type) for event_date in (%s))
order by
last_name
}';
begin
select
listagg(apex_string.format('date ''%0'' "%0"', to_char(event_date, 'YYYY-MM-DD')), ', ')
within group (order by event_date)
into
l_pivot_cols
from
vol_event;
return apex_string.format(l_sql, l_pivot_cols);
end;
Then, for the Attributes/Heading (Type=PL/SQL Function Body) I used:
declare
l_cols varchar2(4000);
begin
select
listagg(to_char(event_date, 'Mon-dd-yy'), ':') within group (order by event_date)
into
l_cols
from
vol_event
;
return 'Last Name:' || l_cols;
end;
That worked out well.