У меня есть таблица со следующей структурой и образцами данных:
Таблица может содержать разные ПОСТАВЩИКИ и ЗАКАЗЫ. Мне нужно отображать в одной строке данные для каждого заказа и поставщика. Так:
и т. д.
Я пробовал PIVOT, но он не работает:
SELECT VENDOR,
order_number,
-- delivery_date,
pickup_date
reasonf_of_delay,
user_name
from table
PIVOT
(count(delivery_date)
FOR order_number
)
🤔 А знаете ли вы, что...
SQL позволяет создавать индексы на нескольких столбцах для оптимизации поиска данных.
Пожалуйста, прочтите документацию для Pivot. Например: https://oracle-base.com/articles/11g/pivot-and-unpivot-operators-11gr1
Если вы хотите выполнить поворот, вы должны знать, для каких значений, возвращаемых для столбца в строке, у вас будут разные столбцы. Используя простой SQL, а не динамический SQL, вы не можете иметь неопределенное количество столбцов. Я не очень понял, какие столбцы должен возвращать ваш SQL.
Вы можете построить что-то подобное со следующим:
CREATE TABLE VENDOR_ORDERS (
VENDOR VARCHAR2(50),
ORDER_NUMBER NUMBER,
DELIVERY_DATE DATE,
REMARKS VARCHAR2(50),
USER_NAME VARCHAR2(50)
);
INSERT INTO VENDOR_ORDERS VALUES ('PEPSI', 1122, TO_DATE('20-DEC-2022', 'DD-MON-YYYY'), 'OPENED', 'John');
INSERT INTO VENDOR_ORDERS VALUES ('PEPSI', 1122, TO_DATE('22-DEC-2022', 'DD-MON-YYYY'), 'REQUESTED', 'Martin');
INSERT INTO VENDOR_ORDERS VALUES ('PEPSI', 1122, TO_DATE('26-DEC-2022', 'DD-MON-YYYY'), 'IN PROCESS', 'Wyatt');
INSERT INTO VENDOR_ORDERS VALUES ('PEPSI', 1122, TO_DATE('10-JAN-2023', 'DD-MON-YYYY'), 'DELAYED', 'Khabib');
INSERT INTO VENDOR_ORDERS VALUES ('PEPSI', 1122, TO_DATE('22-JAN-2023', 'DD-MON-YYYY'), 'IN TRANSIT', 'Karen');
SELECT *
FROM
(
SELECT VENDOR
,ORDER_NUMBER
,DELIVERY_DATE
,REMARKS
,USER_NAME
,ROW_NUMBER() OVER (PARTITION BY VENDOR, ORDER_NUMBER ORDER BY DELIVERY_DATE ASC) AS rn
FROM VENDOR_ORDERS vo
) DS
PIVOT
(
MAX(DELIVERY_DATE) AS DT, MAX(REMARKS) AS R, MAX(USER_NAME) AS UN FOR RN IN ('1', '2', '3', '4', '5')
) PVT
Проблема в том, что в этом случае столбцы PIVOT статичны. Итак, вы можете добавить 10 или 20, что наиболее подходит для вашего случая, и иметь значение NULL, если таких записей не существует.
SELECT Vendor, 'Order 1' AS OrderNumber,
MAX(CASE WHEN RowNum = 1 THEN Delivery_Date END) AS Delivery_Date_1,
MAX(CASE WHEN RowNum = 1 THEN Remarks END) AS Remarks_1,
MAX(CASE WHEN RowNum = 1 THEN User END) AS User_1,
MAX(CASE WHEN RowNum = 2 THEN Delivery_Date END) AS Delivery_Date_2,
MAX(CASE WHEN RowNum = 2 THEN Remarks END) AS Remarks_2,
MAX(CASE WHEN RowNum = 2 THEN User END) AS User_2,
MAX(CASE WHEN RowNum = 3 THEN Delivery_Date END) AS Delivery_Date_3,
MAX(CASE WHEN RowNum = 3 THEN Remarks END) AS Remarks_3,
MAX(CASE WHEN RowNum = 3 THEN User END) AS User_3,
MAX(CASE WHEN RowNum = 4 THEN Delivery_Date END) AS Delivery_Date_4,
MAX(CASE WHEN RowNum = 4 THEN Remarks END) AS Remarks_4,
MAX(CASE WHEN RowNum = 4 THEN User END) AS User_4,
MAX(CASE WHEN RowNum = 5 THEN Delivery_Date END) AS Delivery_Date_5,
MAX(CASE WHEN RowNum = 5 THEN Remarks END) AS Remarks_5,
MAX(CASE WHEN RowNum = 5 THEN User END) AS User_5 FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Vendor, Order ORDER BY Id) AS RowNum FROM [[your_table]]
) т ГДЕ Заказ = 1122 СГРУППИРОВАТЬ ПО ПРОДАВЦАМ
! Не уверен насчет вашего варианта использования, но это может сработать. Если у вас много данных, я бы предложил создать новую таблицу и вставить ее с преобразованиями.
Самый простой способ сделать это — использовать предложение PIVOT, как вы начали. Но вам нужно добавить столько агрегированных показателей, сколько у вас есть столбцов (DELIVERY_DATE, REMARKS, USER#). Кроме того, вам необходимо ранжировать (номер_строки) все строки для ПОСТАВЩИКА, ЗАКАЗА № перед использованием предложения PIVOT, как показано ниже. Наконец, вы можете изменить псевдонимы, созданные предложением PIVOT для ваших столбцов в верхнем SELECT.
SELECT *
FROM (
SELECT T.*,
ROW_NUMBER() OVER(PARTITION BY VENDOR, ORDER# ORDER BY DELIVERY_DATE, ROWNUM) RN
FROM TAB_NAME T
) PIVOT(
MAX(DELIVERY_DATE) AS DELIVERY_DATE
, MAX(REMARKS) AS REMARKS
, MAX(USER#) AS USER#
FOR RN IN (1, 2, 3, 4, 5)
);