oracle 动态实现行转列操作

--用到,case when语句,以及listagg
--
整个流程控制语句 declare txtsqlcostitem varchar(8000); --case when 行转列语句 selectsqltxtcostitem varchar(8000); --case when 行转列语句后查询字段 txtsqlcostitemex varchar(8000); --case when 行转列语句ex selectsqltxtcostitemex varchar(8000); --case when 行转列语句后查询字段ex selectsqltxt varchar(8000); --定义查询字段变量 sqltxtcostitem varchar(8000); --整个子查询语句 begin select listagg('sum(nvl(case when materialofcostid= ''' || to_char(materialofcostid) || ''' then TspTaskVendorApportItems.vtaxinvalue end,0)) as vtaxinvalue' || to_char(MaterialCode), ',') within group(order by materialofcostid, MaterialCode) costitemvalue, listagg('vtaxinvalue' || to_char(MaterialCode), ',') within group(order by materialofcostid, MaterialCode) costitems, listagg('sum(nvl(case when materialofcostid= ''' || to_char(materialofcostid) || ''' then TspTaskVendorApportItems.vtaxexvalue end,0)) as vtaxexvalue' || to_char(MaterialCode), ',') within group(order by materialofcostid, MaterialCode) costitemvalue, listagg('vtaxexvalue' || to_char(MaterialCode), ',') within group(order by materialofcostid, MaterialCode) costitems into txtsqlcostitem, selectsqltxtcostitem, txtsqlcostitemex, selectsqltxtcostitemex --赋值变量 from (select TspTaskVendorApportItems.materialofcostid, materials.MaterialCode from TspTaskVendorApportItems inner join materials on TspTaskVendorApportItems.materialofcostid = materials.MaterialID group by TspTaskVendorApportItems.materialofcostid, materials.MaterialCode); sqltxtcostitem := ' '; selectsqltxt := ' '; -- IF (trim(txtsqlcostitem) is not null) IF (length(trim(txtsqlcostitem)) > 0) --判断流程语句 then sqltxtcostitem := ' select TspTaskMatItems.TaskBillID,TspTaskMatItems.MaterialID,TspTaskMatItems.MatItemID , ' || txtsqlcostitem || ',' || txtsqlcostitemex || ' from TspTaskBills inner join TspTaskMatItems on TspTaskBills.TaskBillID=TspTaskMatItems.TaskBillID inner join TspTaskVendorApportItems on TspTaskMatItems.TaskBillID =TspTaskVendorApportItems.TaskBillID and TspTaskMatItems.MaterialID=TspTaskVendorApportItems.MaterialID and TspTaskVendorApportItems.MatItemID =TspTaskMatItems.MatItemID group by TspTaskMatItems.TaskBillID,TspTaskMatItems.MaterialID,TspTaskMatItems.MatItemID '; selectsqltxt := ',' || selectsqltxtcostitem || ',' || selectsqltxtcostitemex; end if; dbms_output.put_line(sqltxtcostitem); --打印子查询语句 dbms_output.put_line(selectsqltxt); --查询字段 end;

用到的表结构可以自行根据语句的里内容自行创建。

--
create table TspTaskVendorApportItems
    (
        TaskBillID char(20),
        VenItemID varchar(4),
        MaterialofCostID  char(20),
        MatItemID varchar(4),
        MaterialID  char(20),
        VTaxInvalue decimal(20,8),
        VTaxExvalue decimal(20,8));
CREATE TABLE Materials (
  MaterialID char(20) NOT NULL,
  MaterialCode nvarchar2(30) NOT NULL,
  MaterialName nvarchar2(225) NULL);
  CREATE TABLE TspTaskBills(
    TaskBillID char(20) NOT NULL);
  CREATE TABLE TspTaskMatItems(
      TaskBillID char(20) NOT NULL,
      MatItemID varchar(4) NOT NULL,
      MaterialID char(20) NULL);

要实现的是把每一TaskBillID ,MatItemID ,MaterialID 对应的多行MaterialofCostID VTaxInvalue VTaxExvalue 的值转化为个个列

最终查询语句生成如下

select TspTaskMatItems.TaskBillID,
       TspTaskMatItems.MaterialID,
       TspTaskMatItems.MatItemID,
       sum(nvl(case
                    when materialofcostid = '00000000000000000026' then
                     TspTaskVendorApportItems.vtaxinvalue
                  end,
                  0)) as vtaxinvalueFY0001,
       sum(nvl(case
                    when materialofcostid = '00000000000000008251' then
                     TspTaskVendorApportItems.vtaxinvalue
                  end,
                  0)) as vtaxinvalue2019091000010001,
       sum(nvl(case
                    when materialofcostid = '00000000000000008266' then
                     TspTaskVendorApportItems.vtaxinvalue
                  end,
                  0)) as vtaxinvalueFY00011,
       sum(nvl(case
                    when materialofcostid = '00000000000000000026' then
                     TspTaskVendorApportItems.vtaxexvalue
                  end,
                  0)) as vtaxexvalueFY0001,
       sum(nvl(case
                    when materialofcostid = '00000000000000008251' then
                     TspTaskVendorApportItems.vtaxexvalue
                  end,
                  0)) as vtaxexvalue2019091000010001,
       sum(nvl(case
                    when materialofcostid = '00000000000000008266' then
                     TspTaskVendorApportItems.vtaxexvalue
                  end,
                  0)) as vtaxexvalueFY00011
  from TspTaskBills
 inner join TspTaskMatItems
    on TspTaskBills.TaskBillID = TspTaskMatItems.TaskBillID
 inner join TspTaskVendorApportItems
    on TspTaskMatItems.TaskBillID = TspTaskVendorApportItems.TaskBillID
   and TspTaskMatItems.MaterialID = TspTaskVendorApportItems.MaterialID
   and TspTaskVendorApportItems.MatItemID = TspTaskMatItems.MatItemID
 group by TspTaskMatItems.TaskBillID,
          TspTaskMatItems.MaterialID,
          TspTaskMatItems.MatItemID

 结构如下

效果如下

原文地址:https://www.cnblogs.com/liuyudong0825/p/11907552.html