Я искал что-то похожее, и все, чего я мог достичь, - это расширить строки до количества элементов в транзакции и сгруппировать их в ячейки. Хотя не очень элегантно. Более того, поскольку в SQL Server агрегирование строк по-прежнему очень громоздко (Oracle, я скучаю по тебе!), Я должен пропустить последнюю часть. Я имею в виду подсчет в один ряд ..
Мое решение заключается в следующем:
Пример таблицы транзакций:
INSERT INTO transactions
(trans_id, item, cnt) VALUES
('1','A','50'),
('2','A','140'),
('3','B','100'),
('4','C','80');
GO
Создать фиктивную таблицу последовательности, которая содержит числа от 1 до 1000 (я предполагаю, что максимально допустимое количество для элемента в одной транзакции равно 1000):
CREATE TABLE numseq (n INT NOT NULL IDENTITY) ;
GO
INSERT numseq DEFAULT VALUES ;
WHILE SCOPE_IDENTITY() < 1000 INSERT numseq DEFAULT VALUES ;
GO
Теперь мы можем сгенерировать временную таблицу из таблицы транзакций, в которой каждая транзакция и элемент существуют "cnt" раз в подзапросе, а затем присвоить номера бинам с использованием деления и сгруппировать по номеру бина :
SELECT bin_nr, item, count(*) count_in_bin
INTO result
FROM (
SELECT t.item, ((row_number() over (order by t.item, s.n) - 1) / 160) + 1 as bin_nr
FROM transactions t
INNER JOIN numseq s
ON t.cnt >= s.n -- join conditionally to repeat transaction rows "cnt" times
) a
GROUP BY bin_id, item
ORDER BY bin_id, item
GO
Результат:
bin_id item count_in_bin
1 A 160
2 A 30
2 B 100
2 C 30
3 C 50
В Oracle последний шаг будет таким простым:
SELECT bin_id, WM_CONCAT(CONCAT(item,'(',count_in_bin,')')) contents
FROM result
GROUP BY bin_id