i am unable to model the query with the XMLTable approach,as in this case i have to use 2 views to query
You can't use ora:view, but can use the same principle with XMLTable and extracting the columns; the trick is to generate the XML view of the data with dbms_xmlgen.getxmltype(), passing that your original query as a string, but manipulating that query string to only include the last_login column if the version is > 11 - which you can get by cross-joining to v$instance.
This is a bit rough and messy but I think does what you want:
select username, profile, account_status,
to_char(ctime, 'DD-MON-YYYY HH24:MI:SS') ctime,
to_char(ptime, 'DD-MON-YYYY HH24:MI:SS') ptime,
default_tablespace, temporary_tablespace, external_name, authentication_type,
to_char(last_login, 'DD-MON-YYYY HH24:MI:SS') last_login
from v$instance i
cross join xmltable('/ROWSET/ROW'
passing dbms_xmlgen.getxmltype(
q'^
select a.username, a.profile, a.account_status, a.default_tablespace,
a.temporary_tablespace, a.external_name, a.authentication_type,
^' || case when to_number(substr(i.version, 1, instr(i.version, '.') - 1)) > 11
then q'^ to_char(a.last_login,'YYYY-MM-DD"T"HH24:MI:SS') last_login,^'
end || q'^
to_char(b.ctime, 'YYYY-MM-DD"T"HH24:MI:SS') ctime,
to_char(b.ptime,'YYYY-MM-DD"T"HH24:MI:SS') ptime
from dba_users a
left join sys.user$ b on b.name = a.username
^')
columns
username, profile, account_status, default_tablespace, temporary_tablespace,
external_name, authentication_type, ctime timestamp, ptime timestamp, last_login timestamp
) x;
It works in 19c anyway; I don't have an 11g database to try it against, but it should just return null in the last_login column.
The inner bit is probably most confusing, where it builds the dynamic query string:
q'^
select a.username, a.profile, a.account_status, a.default_tablespace,
a.temporary_tablespace, a.external_name, a.authentication_type,
^' || case when to_number(substr(i.version, 1, instr(i.version, '.') - 1)) > 11
then q'^ to_char(a.last_login,'YYYY-MM-DD"T"HH24:MI:SS') last_login,^'
end || q'^
to_char(b.ctime, 'YYYY-MM-DD"T"HH24:MI:SS') ctime,
to_char(b.ptime,'YYYY-MM-DD"T"HH24:MI:SS') ptime
from dba_users a
left join sys.user$ b on b.name = a.username
^'
That's mostly your original, reordered a bit and with modern join syntax and columns prefixed with the alias of the table they come from. Because of the case expression, in 11g that will evaluate to:
select a.username, a.profile, a.account_status, a.default_tablespace,
a.temporary_tablespace, a.external_name, a.authentication_type,
to_char(b.ctime, 'YYYY-MM-DD"T"HH24:MI:SS') ctime,
to_char(b.ptime,'YYYY-MM-DD"T"HH24:MI:SS') ptime
from dba_users a
left join sys.user$ b on b.name = a.username
while in 12c and 19c etc. it will evaluate to:
select a.username, a.profile, a.account_status, a.default_tablespace,
a.temporary_tablespace, a.external_name, a.authentication_type,
to_char(a.last_login,'YYYY-MM-DD"T"HH24:MI:SS') last_login,
to_char(b.ctime, 'YYYY-MM-DD"T"HH24:MI:SS') ctime,
to_char(b.ptime,'YYYY-MM-DD"T"HH24:MI:SS') ptime
from dba_users a
left join sys.user$ b on b.name = a.username
i.e. the same query but with the last_login reference added.
The three date columns are being formatted as strings in ISO-8601 format. That is so that when they are extracted with the XMLTable columns clause they can be declared as timestamps, and will be converted to that data type automatically.
The main query select list can then format those timestamps however you want.