I have the below table. I need to create columns based off the column CCL. The values in column CCL are unknown. I'm not sure where to begin here. Any help would be appreciated.
TABLEA
ID CCL Flag
1 john x
1 adam x
1 terry
1 rob x
2 john x
Query:
SELECT *
FROM TABLEA
Output:
ID John Adam Terry Rob
1 x x x
2 x
Using dynamic sql for a result where the columns are unknown at the time of executing is a bit of a hassle in Oracle compared to certain other RDMBS.
Because the record type for the output is yet unknown, it can't be defined beforehand.
In Oracle 11g, one way is to use a nameless procedure that generates a temporary table with the pivoted result.
Then select the results from that temporary table.
Returns:
You can find a test on db<>fiddle here
In Oracle 11g, another cool trick (created by Anton Scheffer) to be used can be found in this blog. But you'll have to add the pivot function for it.
The source code can be found in this zip
After that the SQL can be as simple as this:
You'll find a test on db<>fiddle here
Oracle must know all the column in select list on PARSING stage.
This has a couple of consequences
It's not possible for Oracle to change the column list of the query without re-parsing it. Regardless what is supposed to impact that - whether it's distinct list of values in some column or something else. In other words you cannot expect Oracle to add new columns to output if you added new value to CCL column in your example.
In each and every query you must specify explicitly all the columns in select list unless you use
"*"
with table alias. If you use"*"
then Oracle gets column list from metadata and if you modify metadata (i.e. run DDL on a table) then Oracle re-parses query.So the best option to deal with "Dynamic Pivoting" is to pivot and format result in the UI. However, there are still some options in database which you may want to consider.
Generating XML with pivoted result and parsing it.
Do pivot for XML and then parse results. In this case, eventually, you have to specify pivoted columns one way or another.
In below example you do NOT have to provide list of the values for CCL, the only literals you specify are: pivoted expression (FLAG) and column used for pivoting (CCL).
You may have noticed 2 important details
In fact, each pivoted column is represented using two columns in result - one for caption and one for value
Names are ordered so you cannot preserver order like in your example ('john', 'adam', 'terry', 'rob'), moreover one column may represent different names like NAME1 represents values for 'adam' in first row and 'john' in second row.
It's possible to use only indices to get the same output.
But still there are two columns for each pivoted column in the output.
Below query returns exactly the same data as in your example
But wait... all the values for CCL are specified in the query. This is because column caption cannot depend on the data in the table. So what is the point in pivoting for XML if you could have just hardcoded all values in for clause with the same success? One of the ideas is that Oracle SQL engine transposes query result and the tool which displays output just has to properly parse XML. So you split pivoting logic into two layers. XML parsing can be done outside SQL, say, in your application.
ODCI table interface
There is already a link in another answer to Anton's solution. You can also check an example here. And, of course, it's explained in detail in Oracle Documentation.
Polymorphic Table Functions
One more advanced technology has been introduces in Oracle 18 - Polymorphic Table Functions. But again, you should not expect that column list of your query will change after you added new value to CCL. It can change only after re-parsing. There is a way to force hard parse before each excution, but that is another topic.
Dynamic SQL
Finally, as also already pointed out in the comments, you can use good old DSQL. First step - generate SQL statement based on the table contents. Second step - execute it.