Oracle SQL 中如何对数据进行分层?

问题描述 投票:0回答:1

所以我需要从 Oracle DB 中提取数据。

可以说来自多个表。

1) 供应商,2) 采购订单,3) 采购行

供应商有供应商 ID、供应商编号、供应商名称栏。 除了供应商 ID 列外,采购订单还包含 ID、编号、描述。 采购行除了采购订单 ID 列之外,还有 ID、行号、行描述、行金额。

因此我们在所有 3 个表之间有一个直接映射,但想要提取如下数据。可以吗?

enter image description here

sql oracle-database
1个回答
0
投票

一种选择是使用 Row_Number() Over() 分析函数和 Case 表达式:

--      S aa m p l e    D a t a : 
Create Table SUPPLIER 
  ( SUPPLIER_ID Number(6), SUPPLIER_NUMBER Number(3), SUPPLIER_NAME Varchar2(32) );
Insert Into SUPPLIER VALUES
  ( 1, 100, 'ABCD' );
--
Create Table PURCHASE_ORDER 
  ( PO_ID Number(6), SUPPLIER_ID Number(6), PO_NUMBER Number(3), PO_DESCRIPTION Varchar2(255) );
Insert Into PURCHASE_ORDER 
  ( Select 1, 1, 1, 'Food' From Dual Union All
    Select 2, 1, 2, 'Dress' From Dual Union All
    Select 3, 1, 3, 'Software' From Dual
  );
--
Create Table PURCHASE_LINES 
  ( PL_ID Number(6), PO_ID Number(6), PL_NUMBER Number(3), PL_DESCRIPTION Varchar2(255), PL_AMOUNT Number(14, 2) );
Insert Into PURCHASE_LINES  
  ( Select 1, 1, 1, 'Line1',  100 From Dual Union All
    Select 2, 1, 2, 'Line2',  100 From Dual Union All
    Select 3, 1, 3, 'Line3',  100 From Dual Union All
    Select 4, 2, 1, 'Line1',   50 From Dual Union All
    Select 5, 2, 2, 'Line2',   75 From Dual Union All
    Select 6, 3, 1, 'Line1', 1000 From Dual Union All
    Select 7, 3, 2, 'Line2',  500 From Dual 
  );
--      S Q L :  
SELECT Case When S_RN = 1 Then SUPPLIER_ID End as SUPPLIER_ID,
       Case When S_RN = 1 Then SUPPLIER_NAME End as SUPPLIER_NAME,
       Case When S_RN = 1 Then SUPPLIER_NUMBER End as SUPPLIER_NUMBER,
      --
       Case When PO_RN = 1 Then PO_NUMBER End as PO_NUMBER, 
       Case When PO_RN = 1 Then PO_DESCRIPTION End as PO_DESCRIPTION, 
      --
       PL_NUMBER, PL_DESCRIPTION, PL_AMOUNT
FROM ( Select     Row_Number() Over(Partition By s.SUPPLIER_ID Order By po.PO_ID, pl.PL_ID) as S_RN, 
                  s.SUPPLIER_ID, s.SUPPLIER_NAME, s.SUPPLIER_NUMBER, 
                  Row_Number() Over(Partition By s.SUPPLIER_ID, pl.PO_ID Order By po.PO_ID, pl.PL_ID) as PO_RN,
                  po.PO_NUMBER, po.PO_DESCRIPTION,
                  pl.PL_NUMBER, pl.PL_DESCRIPTION, pl.PL_AMOUNT
       From       SUPPLIER s
       Left Join PURCHASE_ORDER po ON(po.SUPPLIER_ID = s.SUPPLIER_ID)
       Left Join PURCHASE_LINES pl ON(pl.PO_ID = po.PO_ID And po.SUPPLIER_ID = s.SUPPLIER_ID)
     );

结果:

供应商_ID SUPPLIER_NAME SUPPLIER_NUMBER PO_NUMBER PO_描述 PL_NUMBER PL_描述 PL_AMOUNT
1 ABCD 100 1 食物 1 1号线 100
2 2号线 100
3 3号线 100
2 连衣裙 1 1号线 50
2 2号线 75
3 软件 1 1号线 1000
2 2号线 500

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.