oracle 在SQL中将行显示为列

krugob8w  于 2023-02-18  发布在  Oracle
关注(0)|答案(4)|浏览(160)

我有一个表,它具有以下结构和示例数据:
| 供货商|订单|交货日期|备注|用户|
| - ------|- ------|- ------|- ------|- ------|
| 佩西|小行星|二十二年十二月二十日|开放|约翰|
| 佩西|小行星|二十二年十二月二十二日|要求|马丁|
| 佩西|小行星|二十二年十二月二十六日|过程中|怀亚特|
| 佩西|小行星|2023年1月10日|延迟|哈比|
| 佩西|小行星|2023年1月22日|运输途中|卡伦|
表可以包含不同的供应商和订单。我需要在一行中显示每个订单和供应商的数据。如下所示:
| 供货商|订单|交付日期1|备注_1|用户_1|交付日期2|备注_2|用户_2|交货日期3|备注_3|用户_3|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 佩西|小行星|二十二年十二月二十日|开放|约翰|二十二年十二月二十二日|要求|马丁|二十二年十二月二十六日|过程中|怀亚特|
等等
我尝试过PIVOT,但它不起作用:

SELECT VENDOR,
         order_number,
        -- delivery_date,
         pickup_date
         reasonf_of_delay,
         user_name
from table
PIVOT
(count(delivery_date)
 FOR order_number
 )
gmxoilav

gmxoilav1#

您可以使用以下代码构建类似的内容:

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值。

zy1mlcev

zy1mlcev2#

最简单的方法是像开始时那样使用***PIVOT子句***。但是,您需要添加与列一样多的聚合度量(交付日期、备注、用户编号)。此外,您还需要对(row_number)每个VENDOR、ORDER#的所有行,然后使用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)
);

demo on db<>fiddle

7kjnsjlb

7kjnsjlb3#

请阅读透视的文档。例如:https://oracle-base.com/articles/11g/pivot-and-unpivot-operators-11gr1
如果你想透视你必须知道哪些值返回给一行中的一列,你将有不同的列。使用普通SQL而不是动态SQL,你不能有一个不确定的列数。我真的不明白你的SQL必须返回哪些列。

to94eoyn

to94eoyn4#

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]]

)t其中订单= 1122按供应商分组
!不确定你的用例,但这可能会起作用。如果你有很多数据,我会建议创建一个新表,并通过转换插入。

相关问题