我有一个现有的表,例如:
CREATE TABLE ES_DEVISES (
NOM VARCHAR2(500),
DEVISE VARCHAR2(5),
ORDRES NUMBER(5,0)
)
-- For testing purposes :
INSERT INTO ES_DEVISES VALUES ('ES1','CHF',157);
INSERT INTO ES_DEVISES VALUES ('ES1','USD',1328);
INSERT INTO ES_DEVISES VALUES ('ES2','AUD',5);
INSERT INTO ES_DEVISES VALUES ('ES1','AUD',23);
INSERT INTO ES_DEVISES VALUES ('ES1','CNY',17);
INSERT INTO ES_DEVISES VALUES ('ES1','INR',17);
INSERT INTO ES_DEVISES VALUES ('ES2','CNY',1);
INSERT INTO ES_DEVISES VALUES ('ES2','INR',4);
INSERT INTO ES_DEVISES VALUES ('ES2','USD',218);
INSERT INTO ES_DEVISES VALUES ('ES2','CHF',42);
我将行绕到这样的列,并返回所需的输出:
SELECT * FROM ES_DEVISES
PIVOT (
MAX(ORDRES) FOR DEVISE IN ('USD' USD,'CHF' CHF,'CNY' CNY,'INR' INR,'AUD' AUD)
);
-- Output :
NOM USD CHF CNY INR AUD
---------------- ---------- ---------- ---------- ---------- ----------
ES1 1328 157 17 17 23
ES2 218 42 1 4 5
现在,随着一些变化,表ES_DEVISES
将包含随机单位(ES1,ES2,ES3等)和随机货币(USD,EUR,XRP,BTC等),因此上面的查询将不再有效。我发现this answer建议使用PIVOT XML
,因此查询变为:
SELECT NOM, DEVISE_XML
FROM ES_DEVISES
PIVOT XML(
MAX(ORDRES) FOR DEVISE IN (SELECT DEVISE FROM NEW_TABLE_FOR_CURRENCIES)
) t;
-- Output :
NOM DEVISE_XML
---------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ES1 <PivotSet><item><column name = "DEVISE">AUD</column><column name = "MAX(ORDRES)">23</column></item><item><column name = "DEVISE">CHF</column><column name = "MAX(ORDRES)">157</column></item><item><column name = "DEVISE">CNY</column><column name = "MAX(ORDRES)">17</column></item><item><column name = "DEVISE">INR</column><column name = "MAX(ORDRES)">17</column></item><item><column name = "DEVISE">USD</column><column name = "MAX(ORDRES)">1328</column></item></PivotSet>
ES2 <PivotSet><item><column name = "DEVISE">AUD</column><column name = "MAX(ORDRES)">5</column></item><item><column name = "DEVISE">CHF</column><column name = "MAX(ORDRES)">42</column></item><item><column name = "DEVISE">CNY</column><column name = "MAX(ORDRES)">1</column></item><item><column name = "DEVISE">INR</column><column name = "MAX(ORDRES)">4</column></item><item><column name = "DEVISE">USD</column><column name = "MAX(ORDRES)">218</column></item></PivotSet>
现在的下一步是解析XML,以便返回到看起来像第一个输出的结果集。现在的问题是DEVISE_XML
字段不包含NOM
字段,我找不到将XML解析为动态列的方法,我尝试使用XMLTABLE
,但它让我回到类似SELECT * FROM ES_DEVISES
之类的地方。
我的问题是:有没有办法:
1)返回如下所示的XML:
<PivotSet>
<row>
<unit>ES1</unit>
<column name="AUD">23</column>
<column name="CHF">157</column>
<column name="CNY">17</column>
<column name="INR">17</column>
<column name="USD">1328</column>
</row>
<row>
<unit>ES2</unit>
<column name="AUD">218</column>
<column name="CHF">42</column>
<column name="CNY">1</column>
<column name="INR">4</column>
<column name="USD">5</column>
</row>
</PivotSet>
2)动态解析XML以返回所需的输出(看起来应该像第一个查询的输出)。
PS:我在网络上看到了许多解决方案,例如使用LISTAGG
或使用字符串构建查询并使用EXECUTE IMMEDIATE
执行查询。但是我对此并不感兴趣,因为我可以使用JAVA轻松地做到这一点,但是这个问题的目的是找到一个清晰,易于维护的查询,该查询可以完成PROCEDURE
中的所有工作。
答案 0 :(得分:1)
我正在为项目中的此类需求使用动态PIVOT功能。
我又添加了一行,这是随机的。 -根据您的要求。
CREATE TABLE ES_DEVISES (
NOM VARCHAR2(500),
DEVISE VARCHAR2(5),
ORDRES NUMBER(5,0)
);
-- For testing purposes :
INSERT INTO ES_DEVISES VALUES ('ES1','CHF',157);
INSERT INTO ES_DEVISES VALUES ('ES1','USD',1328);
INSERT INTO ES_DEVISES VALUES ('ES2','AUD',5);
INSERT INTO ES_DEVISES VALUES ('ES1','AUD',23);
INSERT INTO ES_DEVISES VALUES ('ES1','CNY',17);
INSERT INTO ES_DEVISES VALUES ('ES1','INR',17);
INSERT INTO ES_DEVISES VALUES ('ES2','CNY',1);
INSERT INTO ES_DEVISES VALUES ('ES2','INR',4);
INSERT INTO ES_DEVISES VALUES ('ES2','USD',218);
INSERT INTO ES_DEVISES VALUES ('ES2','CHF',42);
INSERT INTO ES_DEVISES VALUES ('ES3','RNDM',100); -- random record added by me
SELECT
*
FROM
TABLE ( PIVOT(' select NOM
, DEVISE
, MAX(ORDRES) ORDRES
from ES_DEVISES
group
by NOM
, DEVISE
'
) );
输出
在这里, PIVOT是功能,我是从AMIS获得的。
以下是下载功能的链接:Dynamic PIVOT
解压缩下载的zip并执行脚本 pivotFun.sql 在数据库中创建PIVOT函数。
希望,您会喜欢它。