Как агрегировать значения из разных строк в SQL (HANA)?
У меня есть таблица отправлений, определенная примерно так (таблица хранится в базе данных HANA, если применимо):
CREATE COLUMN TABLE SHIPMENTS (
ShipmentID INT PRIMARY KEY,
Received INT,
Facility NVARCHAR(10),
Item NVARCHAR(20)
);
Здесь столбец "Получено" обозначает момент времени, в который каждая посылка получена, Услуга - это место, где отправка получена, а Предмет - содержимое отправления.
Я заполнил его данными так:
INSERT INTO SHIPMENTS VALUES (1, 0, 'Factory', 'Production machine');
INSERT INTO SHIPMENTS VALUES (2, 0, 'Office', 'Printer');
INSERT INTO SHIPMENTS VALUES (3, 0, 'Factory', 'Coffee maker');
INSERT INTO SHIPMENTS VALUES (4, 1, 'Office', 'Coffee maker');
INSERT INTO SHIPMENTS VALUES (5, 1, 'Factory', 'Fax Machine');
INSERT INTO SHIPMENTS VALUES (6, 2, 'Office', 'Computers');
INSERT INTO SHIPMENTS VALUES (7, 2, 'Factory', 'Fridge');
INSERT INTO SHIPMENTS VALUES (8, 2, 'Factory', 'Freezer');
INSERT INTO SHIPMENTS VALUES (9, 2, 'Office', 'Fax Machine');
Я хотел бы сделать запрос к базе данных, чтобы найти, в каждый момент времени, какие пункты были получены до этого момента. Основываясь на ответе из другого потока, я начну с этого:
SELECT Facility, Received, STRING_AGG (Item, ';') as Items
FROM (
SELECT * FROM SHIPMENTS
ORDER BY Facility, Received
)
GROUP BY Facility, Received
ORDER BY Facility, Received;
что приводит к
| FACILITY | RECEIVED | ITEMS
---------------------------------------------------------
1 | Factory | 0 | Production Machine;Coffee maker
2 | Factory | 1 | Fax Machine
3 | Factory | 2 | Fridge;Freezer
4 | Office | 0 | Printer
5 | Office | 1 | Coffee maker
6 | Office | 2 | Computers;Fax Machine
Тем не менее, я хотел бы это
| FACILITY | RECEIVED | ITEMS
---------------------------------------------------------
1 | Factory | 0 | Production Machine;Coffee maker
2 | Factory | 1 | Production Machine;Coffee maker;Fax Machine
3 | Factory | 2 | Production Machine;Coffee maker;Fax Machine;Fridge;Freezer
4 | Office | 0 | Printer
5 | Office | 1 | Printer;Coffee maker
6 | Office | 2 | Printer;Coffee maker;Computers;Fax Machine
Т.е. каждая строка отображает то, что получено в этот момент, и все, что уже было получено. Есть ли хороший способ сделать это в SQL?
2 ответа
Вы можете попробовать использовать коррелированный запрос в предложении select для генерации данных CSV, которые вы хотите:
SELECT
Facility,
Received,
(SELECT STRING_AGG (s2.Item, ';') FROM SHIPMENTS s2
WHERE s2.Facility = s1.Facility AND s2.Received <= s1.Received
GROUP BY s2.Facility) AS ITEMS
FROM SHIPMENTS s1
GROUP BY
Facility,
Received
ORDER BY
Facility;
Может быть, было бы неплохо использовать предложение ORDER BY с функцией String_Agg, чтобы убедиться, что конкатенация будет в нужном порядке
select
distinct Facility, Received,
(
select string_agg(s.Item, ';' order by Received, ShipmentID)
from Shipments s
where
s.Facility = t.Facility and
s.Received <= t.Received
) as Items
from Shipments t