Actually, I think the design is good, its just that SQL is NOT intended to be a reporting language, but rather a data query language (but we all misuse it as a quasi-reporting language all the time).
Your proposal (having 32 columns for the different attributes is highly denormalized. It would, for instance, require adding a new column to the table each time a new possible attribute is needed. This is NOT good design.
The design that was proposed originally is actually quite sound. Although the description suggests a fixed number of attributes (3 per job type), in fact, it permits an unlimited number (by simply adding more attribute types in the secondary table) and it also permits a variable number of those attributes per job type (even though the example shows a fixed number of 3). This eliminates unnecessary data in the attribute (secondary table). Although the example doesn't illustrate this, if there are 30+ possibly attributes, and most job types only have a few of these, your approach would create data space (or at least null entries) for most of them for each job type. Not a good design, IMHO.
The problem is that SQL was intended to be used in conjunction with a programming or scripting language (as we often do), not purely by itself. In that context, there is no need to try to do what the original poster asked, i.e., create a "cross-tab" in SQL.
Instead, you would use the query language to create a join of the two tables (a simple join) across the ID/JOB_ID columns which would create each job with all of its attributes as rows (regardless of the number). Then you would use a programming lanugague, scripting language or reporting language to turn that query into a viewable x-tab display or table.
Because most SQL dialects have taken on all sorts of additions, we start to think of SQL as a reporting tool, which it wasn't intended to be.
Jon