Сводная таблица в SQL, но имена мер сохраняются в столбце

#sql #pivot #unpivot

#sql #сводная #отменить

Вопрос:

У меня возникли проблемы с корректным поворотом таблицы.

Мой ввод — это таблица необработанных данных:

  ------ --------- ------------ ---------- 
| YEAR | FACULTY | ADMISSIONS | DROPOUTS |
 ------ --------- ------------ ---------- 
| 2018 | LAW     |         15 |        2 |
| 2019 | LAW     |         18 |        4 |
| 2020 | LAW     |         11 |        1 |
| 2018 | MATH    |         19 |        1 |
| 2019 | MATH    |         17 |        6 |
| 2020 | MATH    |         24 |        5 |
 ------ --------- ------------ ---------- 
  

Я хочу свести годы к строке, но я также хочу сохранить меру для приема и отсева в виде имен строк. Например, я хочу, чтобы таблица выглядела так:

  --------- ------------ ------ ------ ------ 
| FACULTY |  MEASURE   | 2018 | 2019 | 2020 |
 --------- ------------ ------ ------ ------ 
| LAW     | ADMISSIONS |   15 |   18 |   11 |
| LAW     | DROPOUTS   |    2 |    4 |    1 |
| MATH    | ADMISSIONS |   19 |   17 |   24 |
| MATH    | DROPOUTS   |    1 |    6 |    5 |
 --------- ------------ ------ ------ ------ 
  

Я могу сводить годы, используя:

 SELECT * 
FROM 
    (
        SELECT FACULTY, YEAR, ADMINISSION, DROPPUTS 
        FROM TABLE
        PIVOT (SUM (ADMISSIONS) 
        FOR YEAR IN (2018,2019,2020)
    )
  

Но мне нужно свести обе меры и при этом получить столбец имен мер. Есть идеи?

Комментарии:

1. Пометьте свой вопрос базой данных, которую вы используете.

Ответ №1:

Это отключение, затем поворот. Если ваша база данных поддерживает боковые соединения и values() , вы можете сделать:

 select
    t.faculty,
    x.measure,
    sum(case when t.year = 2018 then x.value end) value_2018,
    sum(case when t.year = 2019 then x.value end) value_2019,
    sum(case when t.year = 2020 then x.value end) value_2020
from mytable t
cross apply (values ('admission', admission), ('dropout', dropout)) as x(measure, value)
group by t.faculty, x.measure
  

Ответ №2:

Я бы отказался от использования apply (при условии, что вы используете SQL Server) и повторно сгруппировал:

 select t.faculty, v.measure,
       max(case when year = 2018 then val end) as [2018],
       max(case when year = 2019 then val end) as [2019],
       max(case when year = 2020 then val end) as [2020]
from t cross apply
     (values ('ADMISSIONS', ADMISSIONS), ('DROPOUTS', DROPOUTS)
     ) v(measure, val)
group by t.faculty, v.measure