Pivoting data in SQL (cont.)
Posted by curt on June 17th, 2005In my last sql post I showed a simple example of pivoting data in SQL when we know the values that we would like to pivot. Often, however, I run into the case where I must pivot data for which:
- I don't know the values I need to pivot, or
- there are so many possible values to pivot that I can't possibly give each its own column
A good example of this is summarizing Financial Aid awards by student for a particular term. The university may have thousands of different awards to give out, but a student usually has no more than 10 awards per term.
So, my source table looks something like this:
TERM ID AWARD AMOUNT ---- -- ----- ------ FA04 1 PELL 4050 FA04 1 ESCHOL 500 FA04 1 WKSTDY 2000 FA04 2 PELL 3500 FA04 2 WKSTDY 2000 FA04 3 PELL 4000
Since I can't actually pivot the values into their own columns, I'm going to create AWARD columns 1..n containing the first n awards for each student per term. In order to do this, I need to be able to number the awards per student, and then pivot the number. Oracle's RANK functionality makes this easy:
TERM,
ID,
MAX(CASE WHEN RN = 1 THEN AWARD
ELSE NULL END) AS AWARD_1,
MAX(CASE WHEN RN = 1 THEN AMOUNT
ELSE NULL END) AS AMOUNT_1,
MAX(CASE WHEN RN = 2 THEN AWARD
ELSE NULL END) AS AWARD_2,
MAX(CASE WHEN RN = 2 THEN AMOUNT
ELSE NULL END) AS AMOUNT_2,
MAX(CASE WHEN RN = 3 THEN AWARD
ELSE NULL END) AS AWARD_3,
MAX(CASE WHEN RN = 3 THEN AMOUNT
ELSE NULL END) AS AMOUNT_3,
FROM
(SELECT
RANK() OVER(PARTITION BY
TERM,
ID
ORDER BY
TERM,
ID,
AWARD) AS RN,
AWARD,
AMOUNT
FROM
AWARD_TABLE)
GROUP BY
TERM,
ID)
And the results:
TERM ID AWARD_1 AMOUNT_1 AWARD_2 AMOUNT_2 AWARD_3 AMOUNT_3 ---- -- ------- -------- ------- -------- ------- -------- FA04 1 ESCHOL 500 PELL 4050 WKSTDY 2000 FA04 2 PELL 3500 WKSTDY 2000 FA04 3 PELL 4000


Recent Comments