Вы можете сделать это с помощью кросс-соединения и некоторых операторов case с помощью фиктивного подзапроса, который содержит столько же строк, сколько у вас есть столбцы, которые вы хотите отключить (так как вы хотите, чтобы каждый столбец переходил в свою собственную строку) как так:
WITH your_table AS (SELECT 'Red' Team, 'Adam' usr, 4 Apples, 5 Oranges, 6 Pears FROM dual UNION ALL
SELECT 'Red' Team, 'Avril' usr, 11 Apples, 12 Oranges, 13 Pears FROM dual UNION ALL
SELECT 'Blue' Team, 'David' usr, 21 Apples, 22 Oranges, 23 Pears FROM dual)
-- end of mimicking your table. See SQL below:
SELECT yt.team,
yt.usr,
CASE WHEN d.id = 1 THEN 'Apples'
WHEN d.id = 2 THEN 'Oranges'
WHEN d.id = 3 THEN 'Pears'
END product,
CASE WHEN d.id = 1 THEN yt.apples
WHEN d.id = 2 THEN yt.oranges
WHEN d.id = 3 THEN yt.pears
END count_of_product
FROM your_table yt
CROSS JOIN (SELECT LEVEL ID
FROM dual
CONNECT BY LEVEL <= 3) d -- number of columns to unpivot
ORDER BY team, usr, product;
TEAM USR PRODUCT COUNT_OF_PRODUCT
---- ----- ------- ----------------
Blue David Apples 21
Blue David Oranges 22
Blue David Pears 23
Red Adam Apples 4
Red Adam Oranges 5
Red Adam Pears 6
Red Avril Apples 11
Red Avril Oranges 12
Red Avril Pears 13
Действовать таким образом означает, что у вас есть только пройти через таблицу один раз, а не несколько раз, если вы делаете профсоюз весь метод.
ETA: Вот метод, который Алексей имел в виду - я хотел бы предложить тестирование обоих методов против вашего набора данных (который, мы надеемся, достаточно большой, чтобы быть репрезентативной), чтобы увидеть, какая из них более производительным:
WITH your_table AS (SELECT 'Red' Team, 'Adam' usr, 4 Apples, 5 Oranges, 6 Pears FROM dual UNION ALL
SELECT 'Red' Team, 'Avril' usr, 11 Apples, 12 Oranges, 13 Pears FROM dual UNION ALL
SELECT 'Blue' Team, 'David' usr, 21 Apples, 22 Oranges, 23 Pears FROM dual)
-- end of mimicking your table. See SQL below:
SELECT yt.team,
yt.usr,
CASE WHEN LEVEL = 1 THEN 'Apples'
WHEN LEVEL = 2 THEN 'Oranges'
WHEN LEVEL = 3 THEN 'Pears'
END product,
CASE WHEN LEVEL = 1 THEN yt.apples
WHEN LEVEL = 2 THEN yt.oranges
WHEN LEVEL = 3 THEN yt.pears
END count_of_product
FROM your_table yt
CONNECT BY PRIOR team = team
AND PRIOR usr = usr
AND PRIOR sys_guid() IS NOT NULL
AND LEVEL <= 3
ORDER BY team, usr, product;
TEAM USR PRODUCT COUNT_OF_PRODUCT
---- ----- ------- ----------------
Blue David Apples 21
Blue David Oranges 22
Blue David Pears 23
Red Adam Apples 4
Red Adam Oranges 5
Red Adam Pears 6
Red Avril Apples 11
Red Avril Oranges 12
Red Avril Pears 13
Вы можете сделать это, используя серию союзов, но это было бы довольно уродливо. Вы еще что-то пробовали? –
'select team,« USER », яблоки в качестве продукта из the_table union все выбирают команду« USER », апельсины из таблицы_таблицы ...' –