если исходную таблицу можно трансформировать, то я добавил столбец item_id и получил естественный первичный ключ (department_id, type_id, item_id). Столбец item идёт в довесок и, в общем-то, не нужен.
данные для воспроизведения:
CREATE TABLE `items` (
`department_id` int(10) unsigned NOT NULL,
`type_id` int(10) unsigned NOT NULL,
`item_id` int(10) unsigned NOT NULL,
`item` varchar(255) NOT NULL,
PRIMARY KEY (`department_id`,`type_id`,`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `items` (`department_id`, `type_id`, `item_id`, `item`) VALUES
(1, 1, 1, '1_1_0001'),
(1, 1, 2, '1_1_0002'),
(1, 2, 1, '1_2_0001'),
(1, 3, 1, '1_3_0001'),
(1, 3, 2, '1_3_0002'),
(1, 3, 3, '1_3_0003'),
(1, 3, 4, '1_3_0004'),
(1, 3, 5, '1_3_0005'),
(2, 1, 1, '2_1_0001'),
(2, 2, 1, '2_2_0001'),
(2, 3, 1, '2_3_0001');
Запрос для решения задачи:
SELECT t.department_id,
IFNULL( t1.item, '' ) as type_1,
IFNULL( t2.item, '' ) as type_2,
IFNULL( t3.item, '' ) as type_3,
IFNULL( t4.item, '' ) as type_4
FROM `items` t
LEFT JOIN `items` t1 ON ( t.department_id=t1.department_id AND t.item_id=t1.item_id AND t1.type_id=1 )
LEFT JOIN `items` t2 ON ( t.department_id=t2.department_id AND t.item_id=t2.item_id AND t2.type_id=2 )
LEFT JOIN `items` t3 ON ( t.department_id=t3.department_id AND t.item_id=t3.item_id AND t3.type_id=3 )
LEFT JOIN `items` t4 ON ( t.department_id=t4.department_id AND t.item_id=t4.item_id AND t4.type_id=4 )
GROUP BY t.department_id, t.item_id
Я добавил 4-й столбец для иллюстрации NULL . Таким образом, есть 2 подхода:
1) перед конструированием знать уникальные значения столбца type_id. Тогда надо добавить в таблицу ещё один индекс ( просто INDEX) чисто по этому столбцу, для скорости предварительного запроса.
2) предполагать максимальный type_id и тупо строить по диапазону 1..type_id_max