Как построить запрос SQL для создания матрицы с 3 измерениями? - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть две таблицы mysql (родительская и дочерняя таблицы).Мне нужна матрица для отображения элементов по вертикальной оси, месяца по горизонтальной оси и значения в пересечении

элементов: идентификатор, описание

вхождения: идентификатор, месяц, значение, element_id

Результат должен быть таким:

       |jan|feb|mar|apr|may|
orange | 12| 5 | 32| 12| 33|
apple  | 26| 2 | 45| 65| 59|
lemon  | 10| 9 | 11| 11| 96|
peanuts|  9| 5 | 59| 99| 87|
avocado|  7| 2 | 47|  3| 24|

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Я бы предложил условную агрегацию:

select e.description,
       max(case when o.month = 'jan' then o.value end) as jan,
       max(case when o.month = 'feb' then o.value end) as feb,
       max(case when o.month = 'mar' then o.value end) as mar,
       max(case when o.month = 'apr' then o.value end) as apr,
       max(case when o.month = 'may' then o.value end) as may
from elements e join
     occurrences o
     on e.id = o.id
group by e.description;
0 голосов
/ 07 февраля 2019

Условное агрегирование часто хорошо подходит для этого.

Предполагая, что столбец "месяц" содержит числа в формате "ГГГГММ".

SELECT 
 elem.description,
 SUM(case when ocur.month = 201901 then ocur.value else 0 end) AS `jan`,
 SUM(case when ocur.month = 201902 then ocur.value else 0 end) AS `feb`,
 SUM(case when ocur.month = 201903 then ocur.value else 0 end) AS `mar`,
 SUM(case when ocur.month = 201904 then ocur.value else 0 end) AS `apr`,
 SUM(case when ocur.month = 201905 then ocur.value else 0 end) AS `may`
 -- Add for the other months here
FROM ocurrences ocur
LEFT JOIN elements elem ON elem.id = ocur.element_id
WHERE ocur.month BETWEEN 201901 AND 201912
GROUP BY ocur.element_id, elem.description
ORDER BY ocur.element_id
0 голосов
/ 07 февраля 2019

Как насчет чего-то вроде:

select a.description, b.value as 'jan', c.value as 'feb', d.value as 'mar' from elements a,
(select * from ocurrences where month ='jan') b,
(select * from ocurrences where month ='feb') c,
(select * from ocurrences where month ='mar') d
where a.id = b.element_id 
and a.id = c.element_id 
and a.id = d.element_id 

Схема (MySQL v5.7)

create table elements(id int, description varchar(50));
create table ocurrences(id int, month varchar(10), value int, element_id int);

insert into elements values (1, 'orange');
insert into elements values (2, 'apple');
insert into elements values (3, 'lemons');

insert into ocurrences values (1, 'jan', 12, 1);
insert into ocurrences values (2, 'jan', 26, 2);
insert into ocurrences values (3, 'jan', 10, 3);

insert into ocurrences values (4, 'feb', 5, 1);
insert into ocurrences values (5, 'feb', 2, 2);
insert into ocurrences values (6, 'feb', 9, 3);

insert into ocurrences values (7, 'mar', 32, 1);
insert into ocurrences values (8, 'mar', 45, 2);
insert into ocurrences values (9, 'mar', 11, 3);

Запрос # 1

select a.description, b.value as 'jan', c.value as 'feb', d.value as 'mar' from elements a,
(select * from ocurrences where month ='jan') b,
(select * from ocurrences where month ='feb') c,
(select * from ocurrences where month ='mar') d
where a.id = b.element_id 
and a.id = c.element_id 
and a.id = d.element_id;

| description | jan | feb | mar |
| ----------- | --- | --- | --- |
| orange      | 12  | 5   | 32  |
| apple       | 26  | 2   | 45  |
| lemons      | 10  | 9   | 11  |

Посмотреть на БД Fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...