The trick with this compared to the other questions (e.g. “Oracle convert rows to columns”) is that my column values are arbitrary strings, rather than something I can use with decode. Take this query:
The description table here maps people’s names to descriptions, but each person can have multiple descriptions e.g. “wears a hat” or “is tall”.
Select firstName, lastName,
(Select description from descriptions --This can return any number of rows (0 or more)
where description.firstName = people.firstName
and description.lastName = people.lastName
and rownum <= 3)
from people
where age >= 25;
I would want an output like this:
FIRSTNAME LASTNAME DESCRIPTION1 DESCRIPTION2 DESCRIPTION3
Jeremy Smith Tall Confused (null)
Anne Smith (Null) (Null) (Null)
Mark Davis Short Smart Strong
In the case of less than 3 descriptions, I want nulls there. In the case of more than 3 descriptions, I want to just leave them out.
I am using Oracle 11.1. Can this be done efficiently?
Assuming that you don’t care what order the descriptions are returned in (i.e. Jeremy Smith could just as correctly have a
Description1or “Confused” and aDescription2of “Tall”), you just need to pivot on the row number. If you care about the order the descriptions are returned in, you can add anORDER BYclause to the window function in theROW_NUMBERanalytic functionAs an aside, I’m hoping that you’re actually storing a birth date and computing the person’s age rather than storing the age and assuming that people are updating their age every year.