【问题标题】:Oracle pivot with dynamic data使用动态数据进行 Oracle 数据透视
【发布时间】:2013-05-15 12:31:00
【问题描述】:

我是 oracle 数据库的新手,我正在尝试使用 PIVOT 将行转换为列。我有以下表格..

table 1
solid       solname
--------------
1        xxxxxx
2        yyyyyyy
table2
id      name           abbrv 
----------------------------------
1        test db          tdb
2        Prdocuiton db     pdb

table3
id     solId
-------------
1   1
1   2
1   3
1   4
1   5
1   7
1   8
1   9
1   22
1   23
1   24
1   25
2   26
2   27
1   28
1   29
1   32
1   33
1   34
1   35
1   36
1   37
3   38
1   39
1   40
1   43
1   44

表 3 是表 1 和表 3 的映射表。

我需要创建一个视图,其中包含 table2 中的列和每个 solname 的额外列。所以视图看起来像

id      name           abbrv   xxxxxxx    yyyyyyy
--------------------------------------------------

那么有没有办法在 oracle 数据库中使用 PIVOT 来做到这一点?

【问题讨论】:

  • 如果你想创建一个视图,视图的定义需要在编译时修正。因此,如果您向table1 添加了另一条拖链,则无法将另一列动态添加到视图中。您可以重新创建视图,甚至可以编写一个使用动态 SQL 重新创建视图的存储过程。或者,您可以避免创建视图并可能执行其他可能是动态的操作——例如,返回 SYS_REFCURSOR 的存储函数,这将是完全动态的。但是那样你就没有视野了。您更喜欢哪种方法?
  • 嗨贾斯汀,感谢您的快速响应。我的情况是重新创建视图是更好的选择...所以请告诉我如何在这种情况下使用动态 SQL

标签: oracle dynamic pivot


【解决方案1】:

对于动态 SQL 透视,您需要执行类似的操作:

create or replace view sol_view
as
select 
    t1.solname, 
    t2.name, 
    count(t3.abbrv),
from 
    table1 t1, 
    table2 t2, 
    table3 t3
where 
    t1.solid = t3.solid 
    and t2.id = t3.id
group by
    t1.solname,
    t3.name

select * from table( pivot('select * from sol_view') )

警告:我从未尝试过,但从这里理解了逻辑: http://technology.amis.nl/2006/05/24/dynamic-sql-pivoting-stealing-antons-thunder/

对于静态 SQL 透视,大致按照这些思路进行尝试。但从未尝试或测试过:

with pivot_data as (
    select t1.solname, t2.name, t3.abbrv
from table1 t1, table2 t2, table3 t3
where t1.solid = t3.solid 
and t2.id = t3.id
)
select * 
from pivot_data
pivot ( 
    count(abbrv) 
    for solname 
    in ('xxxxxx','yyyyyyy') 
);

【讨论】:

    【解决方案2】:

    并没有真正定义您要在 xxxx 和 yyyy 列中存储的内容,可能是 1/blank、Y/N、...?但是,您的查询可能类似于以下内容:

    SELECT * FROM (
      SELECT *
      FROM table3 t3
      JOIN table2 t2 USING (id)
      JOIN table1 t1 USING (solid)
    ) PIVOT (
      COUNT(*) FOR (solname) IN (
        ('xxx') AS "XXX",
        ('yyy') AS "YYY"
      )
    )
    

    您可以在My Blog 上找到更多信息和其他参考资料

    【讨论】:

      【解决方案3】:
      TableName - **tblItem**
      Id  ItemName    RecipeName  Quantity
      1   Sugar       mutter paneer   200
      2   Tea     mutter paneer   100
      3   Tomato      mutter paneer   500
      4   Onion       mutter paneer   300
      5   Ginger      mutter paneer   300
      6   Capsicum    mutter paneer   300
      7   Sugar       mutter paneer   200
      8   Tea     mutter paneer   100
      9   Onion       mutter paneer   500
      10  Sugar       mutter paneer   200
      
      V_VALUES varchar2(4000);
      sql_query varchar2(4000);
      
      SELECT
      LISTAGG(''''||ITEMNAME||'''',',')WITHIN GROUP (ORDER BY ITEMNAME)as ITEMNAME
      INTO V_LIST
      FROM(SELECT DISTINCT ITEMNAME FROM tblItem);
      
      sql_query : = 'SELECT * FROM (
                    SELECT ItemName,RecipeName,Sum(Quantity) as Quantity from tblItem group by ItemName,RecipeName)
                    PIVOT ( 
              sum(Quantity) for ItemName in (' ||V_LIST|| ') 
              )';
      
        OPEN p_cursor
           FOR sql_query;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-18
        相关资源
        最近更新 更多