0

How can I convert a list contain 3 column ("x", "y", "value") to a matrix with n rows and n columns?(n equals to count(distinct x))

something like this:

|x    | y | z|
--------------
|a1   | a2| 3|
|a1   | a3| 5|
|a2   | a3| 9|
|a3   | a3| 0|
|.    | . | .|
|.    | . | .|
|a5000| a3| 1|

to the below :

|x     |a1     |a2    |a3 . .   |a5000
---------------------------------------
|a1    |null   |3     |5   ..   |null
|a2    |null   |null  |9   ..   |null
|a3    |null   |null  |0   ..   |null
|.     | .     | .    |    ..   |.
|.     | .     | .    |    ..   |.
|a5000 |null   |null  |1   ..   |null
  • I can't use pivot because I can't write all of y value in query.
parvij
  • 1,381
  • 3
  • 15
  • 31

1 Answers1

0

I assume you want something like:

SELECT * 
  FROM (SELECT * FROM YOUR_TABLE) 
  PIVOT (MAX(Z) 
         FOR Y IN ('A1','A2','A3'..., 'A5000')) 
  ORDER BY TO_NUMBER(SUBSTR(X,2));

And as you mention, you cannot write the query because there are too many 'A' values.

But you can write a query that writes your query:

SELECT 'SELECT * FROM (SELECT * FROM YOUR_TABLE) PIVOT (MAX(Z) FOR Y IN ('
    || LISTAGG('''A'||(LEVEL)||'''', ',') WITHIN GROUP (ORDER BY LEVEL) 
    || ')) ORDER BY TO_NUMBER(SUBSTR(X,2))'
  FROM DUAL 
  CONNECT BY LEVEL <= (SELECT COUNT(DISTINCT X) FROM YOUR_TABLE);

This query will build the query you want. Then launch the resulting query as any other dynamic select.

acesargl
  • 569
  • 3
  • 7