2010-08-13 4 views
3

J'ai ce point de vue de la tablePivot/Crosstab requête dans Oracle 10g (numéro de colonne dynamique)

UserName  Product  NumberPurchaces 
--------  -------  --------------- 
'John Doe' 'Chair'  4 
'John Doe' 'Table'  1 
'Jane Doe' 'Table'  2 
'Jane Doe' 'Bed'  1 

Comment puis-je créer une requête qui fournira ce point de vue de pivot dans Oracle 10g?

UserName Chair Table Bed 
-------- ----- ----- --- 
John Doe 4  1  0 
Jane Doe 0  2  1 

Une façon de le faire dynamiquement? J'ai vu tant d'approches (decode, PL/boucles SQL, les syndicats, pivot 11g)

Mais je n'ai pas encore trouver quelque chose qui fonctionne pour moi en fonction de l'exemple ci-dessus


Modifier : Je ne sais pas le nombre ou le type de produits dans le temps de développement donc ce doit être dynamique

+0

Vous ne pouvez pas. Toute instruction SQL particulière doit renvoyer un resultset avec le même nombre de colonnes, le même nom de colonne et le même type de données que les colonnes –

Répondre

4

Oracle 11g est le premier à soutenir PIVOT/UNPIVOT, vous devez utiliser:

SELECT t.username, 
     MAX(CASE WHEN t.product = 'Chair' THEN t.numberpurchases ELSE NULL END) AS chair, 
     MAX(CASE WHEN t.product = 'Table' THEN t.numberpurchases ELSE NULL END) AS tbl, 
     MAX(CASE WHEN t.product = 'Bed' THEN t.numberpurchases ELSE NULL END) AS bed 
    FROM TABLE t 
GROUP BY t.username 

Vous pouvez utiliser DECODE, mais CASE a été pris en charge depuis 9i.

+1

Thanks !, Comment cela peut-il devenir dynamique maintenant? par exemple. ne sachant pas à l'avance quel est l'ensemble des produits (liste dynamique qui n'est pas connue au moment du design) –

3

Je suppose que l'on devrait écrire du code pour créer dynamiquement la requête. Chaque ligne MAX() est identique à l'exception des chaînes 'CHAIR', 'TABLE', etc. Donc, il faudrait parcourir les données pour trouver tous les produits et construire une seconde requête au fur et à mesure. Ensuite, exécutez cette requête créée dynamiquement.

+0

* rotfl * Vous avez downvoted une réponse d'il y a un an? Vous devez passer une bonne journée :) – MatBailie