I have the following tables:
1. UNIT_OF_MEASURE : columns: UNIT_OF_MEASURE, CODE, DESCRIPTION, VERSION
2. UNIT_OF_MEASURE_TRANS: columns: UNIT_OF_MEASURE_ID_LANGAUGE_ID, DESCRIPTION
3. LANGUAGE: columns: LANGUAGE_ID, LANGUAGE_NAME

What I'm tried to do is to show all unit of measures descriptions in 5 languages. I've successfully done this but as a list, that is, all description in one column repeated in different languages.

SELECT 
    uomt.description, 
    l.language_name
FROM unit_of_measure_trans uomt
INNER JOIN language l ON (uomt.language_id = l.language_id)
WHERE 
  l.language_id IN (25, 22, 82, 34, 27, 52, 10, 90)
order by language_name;

`

Now, I need to improve this to show each group of descriptions in separated column based on the language. So I'll have five columns contain same group of unit of measure descriptions in different language. I tried slef-join but I got cartesian product results, not sure if union all will solve the issue. I've reviewed several posts about transpose here, I'm afraid I could not apply any of them on my case.

有帮助吗?

解决方案

To emulate PIVOT, you can use a combination of CASE, MAX and GROUP BY:

SELECT 
    max(case when language_name = 'English' then uomt.description else null end)
       as english_description,
    max(case when language_name = 'German' then uomt.description else null end)
       as german_description,
    uomt.unit_of_measure_id
FROM unit_of_measure_trans uomt
INNER JOIN language l ON (uomt.language_id = l.language_id)
group by uomt.unit_of_measure_id
order by uomt.unit_of_measure_id;

SQL Fiddle

其他提示

After digging out we will find numerous similar questions, I can systemtically state the answer as follow:
1. In order to transpose columns to rows, you may use UNION ALL here
2. In order to apply PIVOT table you should consider oracle version as follow:
a. Oracle 11g: You can use Built In PIVOT Feature and here
b. Oracle 10g and 9i: You are restricted to use [CASE WHEN][4] expression or [DECODE][5] expression. c. Oracle 8i: You are restricted to use DECODE expression

For my question above, I found the solution as follow:

SELECT uom.code, MAX(CASE WHEN l.language_id = 25 THEN uomt.description ELSE NULL END) AS english, MAX(CASE WHEN l.language_id = 22 THEN uomt.description ELSE NULL END) AS german FROM unit_of_measure uom INNER JOIN unit_of_measure_trans uomt ON (uom.unit_of_measure_id = uomt.unit_of_measure_id) INNER JOIN language l ON (uomt.language_id = l.language_id) WHERE l.language_id IN (25, 22)) GROUP BY uom.code;

Notice that in CASE WHEN expression, if you do not use aggregate function you'll get error unless you remove GROUP BY expression. However, in the later case, you'll get all null values which is rarely useful result

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top